omads/omadsextensions/datamod/src/nsmldatamodbase.cpp
changeset 20 e1de7d03f843
child 54 13ecdfc9a581
equal deleted inserted replaced
19:2691f6aa1921 20:e1de7d03f843
       
     1 /*
       
     2 * Copyright (c) 2005 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:  Versit data stripper and merger.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include <NSmlDataModBase.h>
       
    21 #include "nsmldebug.h"
       
    22 #include "nsmlconstants.h"
       
    23 
       
    24 #include <versit.h>
       
    25 #include <vcal.h>
       
    26 #include <vcard.h>
       
    27 #include <s32mem.h>
       
    28 #include <stringpool.h>
       
    29 #include <vtoken.h>
       
    30 #include <e32property.h>
       
    31 #include <DataSyncInternalPSKeys.h>
       
    32 
       
    33 //Fix to Remove the Bad Compiler Warnings
       
    34 #ifndef __WINS__
       
    35 // This lowers the unnecessary compiler warning (armv5) to remark.
       
    36 // "Warning:  #174-D: expression has no effect..." is caused by 
       
    37 // DBG_ARGS8 macro in no-debug builds.
       
    38 #pragma diag_remark 174
       
    39 #endif
       
    40 
       
    41 // ============================ MEMBER FUNCTIONS ===============================
       
    42 
       
    43 // ------------------------------------------------------------------------------------------------
       
    44 // CNSmlDataModBase::~CNSmlDataModBase
       
    45 // Destructor.
       
    46 // ------------------------------------------------------------------------------------------------
       
    47 EXPORT_C CNSmlDataModBase::~CNSmlDataModBase()
       
    48 	{
       
    49 	}
       
    50 
       
    51 // ------------------------------------------------------------------------------------------------
       
    52 // CNSmlDataModBase::SetOwnStoreFormat
       
    53 // Sets own database format.
       
    54 // ------------------------------------------------------------------------------------------------
       
    55 EXPORT_C void CNSmlDataModBase::SetOwnStoreFormat( CSmlDataStoreFormat& aOwnStoreFormat )
       
    56 	{
       
    57 	_DBG_FILE("CNSmlDataModBase::SetOwnStoreFormat(): begin");
       
    58 	iOwnStoreFormat = &aOwnStoreFormat;
       
    59 	_DBG_FILE("CNSmlDataModBase::SetOwnStoreFormat(): end");
       
    60 	}
       
    61 
       
    62 // ------------------------------------------------------------------------------------------------
       
    63 // CNSmlDataModBase::SetPartnerStoreFormat
       
    64 // Sets remote database format.
       
    65 // ------------------------------------------------------------------------------------------------
       
    66 EXPORT_C void CNSmlDataModBase::SetPartnerStoreFormat( CSmlDataStoreFormat& aRemoteStoreFormat )
       
    67 	{
       
    68 	_DBG_FILE("CNSmlDataModBase::SetPartnerStoreFormat(): begin");
       
    69 	iRemoteStoreFormat = &aRemoteStoreFormat;
       
    70 	_DBG_FILE("CNSmlDataModBase::SetPartnerStoreFormat(): end");
       
    71 	}
       
    72 
       
    73 // ------------------------------------------------------------------------------------------------
       
    74 // CNSmlDataModBase::SetUsedMimeType
       
    75 // Sets mime type that is used for sending and receiving. 
       
    76 // This method can be called separately before every item.
       
    77 // ------------------------------------------------------------------------------------------------
       
    78 EXPORT_C TInt CNSmlDataModBase::SetUsedMimeType( const RStringF aMimeType, const RStringF aMimeVersion )
       
    79 	{
       
    80 	_DBG_FILE("CNSmlDataModBase::SetUsedMimeTypeL(): begin");
       
    81 	iUsedRemoteMimeType = -1;
       
    82 	if ( !iRemoteStoreFormat )
       
    83 		{
       
    84 		_DBG_FILE("CNSmlDataModBase::SetUsedMimeTypeL() - Not Found: end");
       
    85 		return KErrNotFound;
       
    86 		}
       
    87 	else
       
    88 		{
       
    89 		for ( TInt i = 0; i < iRemoteStoreFormat->MimeFormatCount(); i++ )
       
    90 			{
       
    91 			if ( iRemoteStoreFormat->MimeFormat( i ).MimeType().DesC().Compare( aMimeType.DesC() ) == 0 )
       
    92 				{
       
    93 				if ( iRemoteStoreFormat->MimeFormat( i ).MimeVersion().DesC().Compare( aMimeVersion.DesC() ) == 0 )
       
    94 					{
       
    95 					iUsedRemoteMimeType = i;
       
    96 					iMimeType = iRemoteStoreFormat->MimeFormat( i ).MimeType();
       
    97 					iMimeVersion = iRemoteStoreFormat->MimeFormat( i ).MimeVersion();
       
    98 					_DBG_FILE("CNSmlDataModBase::SetUsedMimeTypeL() - Found: end");
       
    99 					return KErrNone;
       
   100 					}
       
   101 				}
       
   102 			}
       
   103 		}
       
   104 	_DBG_FILE("CNSmlDataModBase::SetUsedMimeTypeL() - Not Found: end");
       
   105 	return KErrNotFound;
       
   106 	}
       
   107 	
       
   108 // ------------------------------------------------------------------------------------------------
       
   109 // CNSmlDataModBase::StripTxL
       
   110 // Strips data that is to be transmitted to the sync partner.
       
   111 // ------------------------------------------------------------------------------------------------
       
   112 EXPORT_C void CNSmlDataModBase::StripTxL( CBufBase& aItem )
       
   113 	{
       
   114 	_DBG_FILE("CNSmlDataModBase::StripTxL(): begin");
       
   115 	HBufC8* buf = HBufC8::NewLC(aItem.Size() * 2);
       
   116 	*buf = aItem.Ptr(0);
       
   117 	TPtr8 ptrBuf = buf->Des();
       
   118 
       
   119 	StripL(ptrBuf);
       
   120 
       
   121 	aItem.Reset();
       
   122 	aItem.InsertL(0, ptrBuf);
       
   123 	CleanupStack::PopAndDestroy(); // buf
       
   124 	_DBG_FILE("CNSmlDataModBase::StripTxL(): end");
       
   125 	}
       
   126 
       
   127 // ------------------------------------------------------------------------------------------------
       
   128 // CNSmlDataModBase::MergeRxL
       
   129 // Merges received item with item in exported from the local database.
       
   130 // ------------------------------------------------------------------------------------------------
       
   131 EXPORT_C void CNSmlDataModBase::MergeRxL( CBufBase& aNewItem, CBufBase& aOldItem, TBool aFieldLevel )
       
   132 	{
       
   133 	_DBG_FILE("CNSmlDataModBase::MergeRxL(): begin");
       
   134 	if( NeedsMerge() )
       
   135 		{
       
   136 		HBufC8* b1 = HBufC8::NewLC(aNewItem.Size() + aOldItem.Size());
       
   137 		*b1 = aNewItem.Ptr(0);
       
   138 		TPtr8 ptrB1 = b1->Des();
       
   139 		TPtr8 p2 = aOldItem.Ptr(0);
       
   140 
       
   141 		MergeL( ptrB1, p2, aFieldLevel );
       
   142 
       
   143 		aNewItem.Reset();
       
   144 		aNewItem.InsertL(0, ptrB1);
       
   145 		CleanupStack::PopAndDestroy(); // b1
       
   146 		}
       
   147 	else if ( iUsedRemoteMimeType == -1 )
       
   148 		{
       
   149 		User::Leave( KErrNotFound );
       
   150 		}
       
   151 	_DBG_FILE("CNSmlDataModBase::MergeRxL(): end");
       
   152 	}
       
   153 
       
   154 // ------------------------------------------------------------------------------------------------
       
   155 // CNSmlDataModBase::NeedsMerge
       
   156 // Checks whether merging is needed or not.
       
   157 // ------------------------------------------------------------------------------------------------
       
   158 EXPORT_C TBool CNSmlDataModBase::NeedsMerge()
       
   159 	{
       
   160 	_DBG_FILE("CNSmlDataModBase::NeedsMerge(): begin");
       
   161 	iUsedRemoteMimeType = -1;
       
   162 	if ( !iRemoteStoreFormat )
       
   163 		{
       
   164 		_DBG_FILE("CNSmlDataModBase::NeedsMerge() - EFalse: end");
       
   165 		return EFalse;
       
   166 		}
       
   167 	else
       
   168 		{
       
   169 		for ( TInt i = 0; i < iRemoteStoreFormat->MimeFormatCount(); i++ )
       
   170 			{
       
   171 			if ( iRemoteStoreFormat->MimeFormat( i ).MimeType().DesC().Compare( iMimeType.DesC() ) == 0 )
       
   172 				{
       
   173 				if ( iRemoteStoreFormat->MimeFormat( i ).MimeVersion().DesC().Compare( iMimeVersion.DesC() ) == 0 )
       
   174 					{
       
   175 					iUsedRemoteMimeType = i;
       
   176 					if ( iRemoteStoreFormat->MimeFormat( i ).PropertyCount() > 0 )
       
   177 						{
       
   178 						_DBG_FILE("CNSmlDataModBase::NeedsMerge() - ETrue: end");
       
   179 						return ETrue;
       
   180 						}
       
   181 					}
       
   182 				}
       
   183 			}
       
   184 		}
       
   185 	_DBG_FILE("CNSmlDataModBase::NeedsMerge() - EFalse: end");
       
   186 	return EFalse;
       
   187 	}
       
   188 	
       
   189 // ------------------------------------------------------------------------------------------------
       
   190 // CNSmlDataModBase::CNSmlDataModBase
       
   191 // Basic constructor of class.
       
   192 // ------------------------------------------------------------------------------------------------
       
   193 CNSmlDataModBase::CNSmlDataModBase()
       
   194 	{
       
   195 	iUsedOwnMimeType = -1;
       
   196 	iUsedRemoteMimeType = -1;
       
   197 	}
       
   198 	
       
   199 // ------------------------------------------------------------------------------------------------
       
   200 // CNSmlDataModBase::StripL
       
   201 // Strips data that is to be transmitted to the sync partner.
       
   202 // ------------------------------------------------------------------------------------------------
       
   203 void CNSmlDataModBase::StripL( TDes8& aItem )
       
   204 	{
       
   205 	_DBG_FILE("CNSmlDataModBase::StripL(): begin");
       
   206 	if ( !NeedsMerge() )
       
   207 		{
       
   208 		if ( iUsedRemoteMimeType == -1 )
       
   209 			{
       
   210 			User::Leave( KErrNotFound );
       
   211 			}
       
   212 		return;
       
   213 		}
       
   214 	TBool modified( EFalse );
       
   215 	CVersitParser* parser = ChildCreateParserLC();
       
   216 	RDesReadStream drs( aItem );
       
   217 	CleanupClosePushL( drs );
       
   218 	parser->InternalizeL( drs );
       
   219 
       
   220 	// Now we're ready to start analysis
       
   221 	CArrayPtr<CVersitParser>* entities = parser->ArrayOfEntities( EFalse );
       
   222 	if( entities )
       
   223 		{
       
   224 		for( TInt i = 0; i < entities->Count(); i++ )
       
   225 			{
       
   226 			StripEntityL( entities->At( i ), modified );
       
   227 			}
       
   228 		}
       
   229 	else
       
   230 		{
       
   231 		StripEntityL( parser, modified );
       
   232 		}
       
   233 
       
   234 	// Only update if anything was modified in process
       
   235 	if( modified )
       
   236 		{
       
   237 		aItem.Zero();
       
   238 		RDesWriteStream dws( aItem );
       
   239 		CleanupClosePushL( dws );
       
   240 		parser->ExternalizeL( dws );
       
   241 		dws.CommitL();
       
   242 		CleanupStack::PopAndDestroy(); // dws
       
   243 		}
       
   244 	CleanupStack::PopAndDestroy( 2 ); // drs, parser
       
   245 	_DBG_FILE("CNSmlDataModBase::StripL(): end");
       
   246 	}
       
   247 
       
   248 // ------------------------------------------------------------------------------------------------
       
   249 // CNSmlDataModBase::StripEntityL
       
   250 // Strips data that is to be transmitted to the sync partner from entity.
       
   251 // ------------------------------------------------------------------------------------------------
       
   252 void CNSmlDataModBase::StripEntityL( CVersitParser* aEntity, TBool& aModified ) const
       
   253 	{
       
   254 	_DBG_FILE("CNSmlDataModBase::StripEntityL(): begin");
       
   255 	StripAllNotOnPartnerListL( aEntity, aModified, ETrue );
       
   256 	_DBG_FILE("CNSmlDataModBase::StripEntityL(): end");
       
   257 	}
       
   258 
       
   259 // ------------------------------------------------------------------------------------------------
       
   260 // CNSmlDataModBase::StripAllOnPartnerListL
       
   261 // Strips all data from entity that is supported by remote server.
       
   262 // ------------------------------------------------------------------------------------------------
       
   263 void CNSmlDataModBase::StripAllOnPartnerListL( CVersitParser* aEntity, TBool& aModified, TBool aParamLevelCheck ) const
       
   264 	{
       
   265     _DBG_FILE("CNSmlDataModBase::StripAllOnPartnerListL(): begin");
       
   266 
       
   267     if( iRemoteStoreFormat->MimeFormat( iUsedRemoteMimeType ).PropertyCount() )
       
   268         {
       
   269         
       
   270         // Check correct Data Sync protocol
       
   271         TInt value( EDataSyncNotRunning );
       
   272         TSmlProtocolVersion usedSyncProtocol( ESmlVersion1_2 );
       
   273         TInt error = RProperty::Get( KPSUidDataSynchronizationInternalKeys,
       
   274                                      KDataSyncStatus,
       
   275                                      value );
       
   276         if ( error == KErrNone &&
       
   277              value == EDataSyncRunning )
       
   278             {
       
   279             usedSyncProtocol = ESmlVersion1_1_2;
       
   280             }
       
   281         
       
   282         TBool wasModified( EFalse );
       
   283 
       
   284         CArrayPtr<CParserProperty>* allProps = aEntity->ArrayOfProperties( EFalse );
       
   285         for( TInt i = 0; i < allProps->Count(); ) // Variable i is not increased here because size of count might be changes during loop
       
   286             {
       
   287             const CParserProperty& ownProperty = *allProps->At( i );
       
   288             CParserPropertyValue* ownValue = ownProperty.Value();
       
   289 
       
   290             TBool removeMe( EFalse );
       
   291             
       
   292             for( TInt i2 = 0; i2 < iRemoteStoreFormat->MimeFormat( iUsedRemoteMimeType ).PropertyCount(); i2++ )
       
   293                 {
       
   294                 const CSmlDataProperty& remoteProperty = iRemoteStoreFormat->MimeFormat( iUsedRemoteMimeType ).Property( i2 );
       
   295                 if( !ownProperty.Name().Compare( remoteProperty.Field().Name().DesC() ) )
       
   296                     {
       
   297                     if( remoteProperty.ParamCount() > 0 && aParamLevelCheck )
       
   298                         {
       
   299                         if ( usedSyncProtocol == ESmlVersion1_1_2 )
       
   300                             {
       
   301                             for( TInt i3 = 0; i3 < remoteProperty.ParamCount(); i3++ )
       
   302                                 {
       
   303                                 if( ownProperty.Param( remoteProperty.Param( i3 ).Field().Name().DesC() ) )
       
   304                                     {
       
   305                                     removeMe = ETrue;
       
   306                                     }
       
   307                                 }                           
       
   308                             }
       
   309                         else // ESmlVersion1_2
       
   310                             {
       
   311                             CArrayPtr<CParserParam>* ownerparamarray = ownProperty.ParamArray();
       
   312                             if(ownerparamarray != NULL)
       
   313                                 {
       
   314                                 for(TInt ownerparam = 0; ownerparam < ownerparamarray->Count(); ownerparam++)
       
   315                                     {
       
   316                                     removeMe = EFalse;
       
   317                                     const CParserParam& ownParam = *ownerparamarray->At( ownerparam );
       
   318                                      TPtrC8 ownparamname = ownParam.Name();
       
   319                                      TPtrC8 ownparamvalue = ownParam.Value();
       
   320                                      if(ownparamvalue == _L8(""))
       
   321                                         {
       
   322                                          for(TInt remoteparam = 0; remoteparam < remoteProperty.ParamCount(); remoteparam++)
       
   323                                             {
       
   324                                             TDesC8 remoteparamname = remoteProperty.Param( remoteparam ).Field().Name().DesC();
       
   325                                             const CSmlDataField& field = remoteProperty.Param( remoteparam ).Field();
       
   326 											if(field.EnumValueCount() > 0)
       
   327 												{
       
   328 	                                            for( TInt rmtenumcount = 0; rmtenumcount < field.EnumValueCount(); rmtenumcount++ )
       
   329 													{
       
   330 	                                                TPtrC8 rmtenumvalue = field.EnumValue( rmtenumcount ).DesC();
       
   331 													if( rmtenumvalue.Compare(ownparamname)== 0 )
       
   332 	                                                    {
       
   333 	                                                    removeMe = ETrue;
       
   334 														break;
       
   335 	                                                    }  
       
   336 	                                                } 
       
   337 												}
       
   338 											else
       
   339 												{
       
   340 												removeMe = ETrue;
       
   341 												break;
       
   342 												}
       
   343                                             }
       
   344                                         }
       
   345                                      else
       
   346                                         {
       
   347 										//Handling when the device supports VersitTokenType as "Encoding"    
       
   348 										if(ownparamname == KVersitTokenENCODING)
       
   349 											{
       
   350 											removeMe = ETrue;
       
   351 											}
       
   352 										else
       
   353 											{
       
   354 	                                         for(TInt remoteparam = 0; remoteparam < remoteProperty.ParamCount(); remoteparam++)
       
   355 	                                            {
       
   356 	                                            if(ownparamname.Compare(remoteProperty.Param( remoteparam ).Field().Name().DesC()) == 0)
       
   357 	                                                {
       
   358 	                                                const CSmlDataField& field = remoteProperty.Param( remoteparam ).Field();
       
   359 													if( field.EnumValueCount() > 0 )
       
   360 														{
       
   361 		                                                for( TInt rmtenumcount = 0; rmtenumcount < field.EnumValueCount(); rmtenumcount++ )
       
   362 		                                                    {
       
   363 		                                                     TPtrC8 rmtenumvalue = field.EnumValue( rmtenumcount ).DesC();
       
   364 		                                                     if( rmtenumvalue.Compare(ownparamvalue)== 0 )
       
   365 		                                                         {
       
   366 		                                                         removeMe = ETrue;
       
   367 																 break;
       
   368 		                                                         }  
       
   369 		                                                    } 
       
   370 														}
       
   371 													else
       
   372 														{
       
   373 														removeMe = ETrue;
       
   374 														break;
       
   375 														}
       
   376 	                                                }                                               
       
   377 	                                            }
       
   378 											}
       
   379                                         }
       
   380                                     	if( !removeMe )
       
   381                                         {
       
   382                                         	break;
       
   383                                         }	    
       
   384                                     } 
       
   385                                 }
       
   386                             else
       
   387                                 {
       
   388                                 removeMe = ETrue;
       
   389                                 }
       
   390                             }
       
   391                         }
       
   392                     else
       
   393                         {
       
   394                         removeMe = ETrue;
       
   395                         }
       
   396 
       
   397                     if( removeMe )
       
   398                         {
       
   399                         break;
       
   400                         }
       
   401                     }
       
   402                 }
       
   403             if( removeMe )
       
   404                 {
       
   405                 #ifdef __NSML_DEBUG__
       
   406                     TPtrC8 pn( ownProperty.Name() );
       
   407                     DBG_ARGS8(_S8("CNSmlDataModBase::StripAllOnPartnerListL(): Dropping %S"), &pn);
       
   408                 #endif // __NSML_DEBUG__
       
   409                 delete allProps->At( i );
       
   410                 allProps->Delete( i );
       
   411                 wasModified = ETrue;
       
   412                 aModified = ETrue;
       
   413                 }
       
   414             else
       
   415                 {
       
   416                 #ifdef __NSML_DEBUG__
       
   417                     TPtrC8 pn( ownProperty.Name() );
       
   418                     DBG_ARGS8(_S8("CNSmlDataModBase::StripAllOnPartnerListL(): NOT dropping %S"), &pn);
       
   419                 #endif // __NSML_DEBUG__
       
   420                 i++;
       
   421                 }
       
   422             }
       
   423         // can't use aModified as that may have been set earlier!
       
   424         if( wasModified )
       
   425             {
       
   426             allProps->Compress();
       
   427             }
       
   428         }
       
   429     _DBG_FILE("CNSmlDataModBase::StripAllOnPartnerListL(): end");
       
   430     }
       
   431 
       
   432 // ------------------------------------------------------------------------------------------------
       
   433 // CNSmlDataModBase::StripAllNotOnPartnerListL
       
   434 // Strips all data from entity that is not supported by remote server.
       
   435 // ------------------------------------------------------------------------------------------------
       
   436 void CNSmlDataModBase::StripAllNotOnPartnerListL( CVersitParser* aEntity, TBool& aModified, TBool aParamLevelCheck ) const
       
   437 	{
       
   438     _DBG_FILE("CNSmlDataModBase::StripAllNotOnPartnerListL(): begin");
       
   439     TInt remotepropertycount = iRemoteStoreFormat->MimeFormat( iUsedRemoteMimeType ).PropertyCount();
       
   440     if( iRemoteStoreFormat->MimeFormat( iUsedRemoteMimeType ).PropertyCount() )
       
   441         {
       
   442         
       
   443         // Check correct Data Sync protocol
       
   444         TInt value( EDataSyncNotRunning );
       
   445         TSmlProtocolVersion usedSyncProtocol( ESmlVersion1_2 );
       
   446         TInt error = RProperty::Get( KPSUidDataSynchronizationInternalKeys,
       
   447                                      KDataSyncStatus,
       
   448                                      value );
       
   449         if ( error == KErrNone &&
       
   450              value == EDataSyncRunning )
       
   451             {
       
   452             usedSyncProtocol = ESmlVersion1_1_2;
       
   453             }
       
   454 
       
   455         TBool wasModified( EFalse );
       
   456 
       
   457         CArrayPtr<CParserProperty>* allProps = aEntity->ArrayOfProperties( EFalse );
       
   458         for( TInt i = 0; i < allProps->Count(); ) // Variable i is not increased here because size of count might be changes during loop
       
   459             {
       
   460             const CParserProperty& ownProperty = *allProps->At( i );
       
   461             CParserPropertyValue* ownValue = ownProperty.Value();
       
   462 
       
   463             TBool removeMe( ETrue );
       
   464             
       
   465             for( TInt i2 = 0; i2 < iRemoteStoreFormat->MimeFormat( iUsedRemoteMimeType ).PropertyCount(); i2++ )
       
   466                 {
       
   467                 const CSmlDataProperty& remoteProperty = iRemoteStoreFormat->MimeFormat( iUsedRemoteMimeType ).Property( i2 );
       
   468                 TPtrC8 remotename = remoteProperty.Field().Name().DesC();
       
   469                 if( !ownProperty.Name().Compare( remoteProperty.Field().Name().DesC() ) )
       
   470                     {
       
   471                     TInt remoteparamcount = remoteProperty.ParamCount();
       
   472                     if( remoteProperty.ParamCount() > 0 && aParamLevelCheck )
       
   473                         {
       
   474                         if ( usedSyncProtocol == ESmlVersion1_1_2 )
       
   475                             {
       
   476                             const CParserProperty* p = allProps->At( i );
       
   477                             TInt entityParamCount = (( CNSmlProperty* )p)->ParamCount();
       
   478                             if( entityParamCount > 0)
       
   479                             {
       
   480                             for( TInt i3 = 0; i3 < remoteProperty.ParamCount(); i3++ )
       
   481                                 {
       
   482                                 TPtrC8 remoteparamname = remoteProperty.Param( i3 ).Field().Name().DesC();
       
   483                                 if( ownProperty.Param( remoteProperty.Param( i3 ).Field().Name().DesC() ) )
       
   484                                     {
       
   485                                     removeMe = EFalse;
       
   486                                     }
       
   487                                 }                           
       
   488                             }
       
   489                             else
       
   490                             {
       
   491                                 removeMe = EFalse;
       
   492                             }
       
   493                             }
       
   494                         else // ESmlVersion1_2
       
   495                             {
       
   496                             CArrayPtr<CParserParam>* ownerparamarray = ownProperty.ParamArray();
       
   497                             if(ownerparamarray != NULL)
       
   498                                 {
       
   499                                 for(TInt ownerparam = 0; ownerparam < ownerparamarray->Count(); ownerparam++)
       
   500                                     {
       
   501 									removeMe = ETrue;
       
   502                                     const CParserParam& ownParam = *ownerparamarray->At( ownerparam );
       
   503                                      TPtrC8 ownparamname = ownParam.Name();
       
   504                                      TPtrC8 ownparamvalue = ownParam.Value();
       
   505                                      if(ownparamvalue == _L8(""))
       
   506                                         {
       
   507                                          for(TInt remoteparam = 0; remoteparam < remoteProperty.ParamCount(); remoteparam++)
       
   508                                             {
       
   509                                             TDesC8 remoteparamname = remoteProperty.Param( remoteparam ).Field().Name().DesC();
       
   510                                             const CSmlDataField& field = remoteProperty.Param( remoteparam ).Field();
       
   511 											if( field.EnumValueCount() > 0)
       
   512 												{
       
   513 												for( TInt rmtenumcount = 0; rmtenumcount < field.EnumValueCount(); rmtenumcount++ )
       
   514 													{
       
   515 													TPtrC8 rmtenumvalue = field.EnumValue( rmtenumcount ).DesC();
       
   516 													if( rmtenumvalue.Compare(ownparamname)== 0 )
       
   517 														{
       
   518 														removeMe = EFalse;
       
   519 														break;
       
   520 														}
       
   521 													} 
       
   522 												}
       
   523 											else
       
   524 												{
       
   525 												removeMe = EFalse;
       
   526 												break;
       
   527 												}											
       
   528                                             }
       
   529                                         }
       
   530                                      else
       
   531                                         {
       
   532 										//Handling when the device supports VersitTokenType as "Encoding"    
       
   533 										if(ownparamname == KVersitTokenENCODING)
       
   534 											{
       
   535 											removeMe = EFalse;
       
   536 											}
       
   537 										else
       
   538 											{
       
   539 	                                         for(TInt remoteparam = 0; remoteparam < remoteProperty.ParamCount(); remoteparam++)
       
   540 	                                            {
       
   541 	                                            TDesC8 remoteparamname = remoteProperty.Param( remoteparam ).Field().Name().DesC();
       
   542 	                                            if(ownparamname.Compare(remoteProperty.Param( remoteparam ).Field().Name().DesC()) == 0)
       
   543 	                                                {
       
   544 	                                                const CSmlDataField& field = remoteProperty.Param( remoteparam ).Field();
       
   545 													if( field.EnumValueCount() > 0)
       
   546 														{
       
   547 		                                                for( TInt rmtenumcount = 0; rmtenumcount < field.EnumValueCount(); rmtenumcount++ )
       
   548 		                                                    {
       
   549 		                                                     TPtrC8 rmtenumvalue = field.EnumValue( rmtenumcount ).DesC();
       
   550 		                                                     if( rmtenumvalue.Compare(ownparamvalue)== 0 )
       
   551 		                                                         {
       
   552 		                                                         removeMe = EFalse;
       
   553 																 break;
       
   554 		                                                         }  
       
   555 		                                                    }
       
   556 														}
       
   557 													else
       
   558 														{
       
   559 														removeMe = EFalse;
       
   560 														break;
       
   561 														}
       
   562 	                                                }
       
   563 												}
       
   564 											}                                 
       
   565                                         }
       
   566                                         if( removeMe )
       
   567                                         {
       
   568                                         	break;
       
   569                                         }	
       
   570                                     } 
       
   571                                 }
       
   572                             else
       
   573                                 {
       
   574                                 removeMe = EFalse;
       
   575                                 }
       
   576                             }
       
   577                         }
       
   578                     else
       
   579                         {
       
   580                         removeMe = EFalse;
       
   581                         }
       
   582 
       
   583                     if( !removeMe )
       
   584                         {
       
   585                         break;
       
   586                         }
       
   587                     }
       
   588                 }
       
   589             if( removeMe )
       
   590                 {
       
   591                 #ifdef __NSML_DEBUG__
       
   592                     TPtrC8 pn( ownProperty.Name() );
       
   593                     DBG_ARGS8(_S8("CNSmlDataModBase::StripAllNotOnPartnerListL(): Dropping %S"), &pn);
       
   594                 #endif // __NSML_DEBUG__
       
   595                 delete allProps->At( i );
       
   596                 allProps->Delete( i );
       
   597                 wasModified = ETrue;
       
   598                 aModified = ETrue;
       
   599                 }
       
   600             else
       
   601                 {
       
   602                 #ifdef __NSML_DEBUG__
       
   603                     TPtrC8 pn( ownProperty.Name() );
       
   604                     DBG_ARGS8(_S8("CNSmlDataModBase::StripAllNotOnPartnerListL(): NOT dropping %S"), &pn);
       
   605                 #endif // __NSML_DEBUG__
       
   606                 i++;
       
   607                 }
       
   608             }
       
   609         // can't use aModified as that may have been set earlier!
       
   610         if( wasModified )
       
   611             {
       
   612             allProps->Compress();
       
   613             }
       
   614         }
       
   615     _DBG_FILE("CNSmlDataModBase::StripAllNotOnPartnerListL(): end");
       
   616     }
       
   617 
       
   618 // ------------------------------------------------------------------------------------------------
       
   619 // CNSmlDataModBase::MergeL
       
   620 // Merges data from old item to new item.
       
   621 // ------------------------------------------------------------------------------------------------
       
   622 void CNSmlDataModBase::MergeL( TDes8& aNewItem, const TDesC8& aOldItem,TBool aFieldLevel )
       
   623 	{
       
   624 	TBool modified( EFalse );
       
   625 	CVersitParser* newItemParser = ChildCreateParserLC();
       
   626 	RDesReadStream newStream( aNewItem );
       
   627 	CleanupClosePushL( newStream );
       
   628 	newItemParser->InternalizeL( newStream );
       
   629 	CVersitParser* oldItemParser = ChildCreateParserLC();
       
   630 	RDesReadStream oldStream( aOldItem );
       
   631 	CleanupClosePushL( oldStream );
       
   632 	oldItemParser->InternalizeL( oldStream );
       
   633 
       
   634 	// Now we're ready to start analysis
       
   635 	CArrayPtr<CVersitParser>* newEntities = newItemParser->ArrayOfEntities( EFalse );
       
   636 	CArrayPtr<CVersitParser>* oldEntities = oldItemParser->ArrayOfEntities( ETrue );
       
   637 
       
   638 	if( newEntities && oldEntities )
       
   639 		{
       
   640 		CleanupPtrArrayPushL( oldEntities );
       
   641 		for( TInt i = 0; ( i < newEntities->Count() ) && ( i < oldEntities->Count() ); i++ )
       
   642 			{
       
   643 			MergeEntityL( newEntities->At( i ), oldEntities->At( i ), modified, aFieldLevel );
       
   644 			}
       
   645 		CleanupStack::PopAndDestroy(); // oldEntities
       
   646 		}
       
   647 	else
       
   648 		{
       
   649 		MergeEntityL( newItemParser, oldItemParser, modified, aFieldLevel );
       
   650 		}
       
   651 
       
   652 	// Only update if anything was modified in process
       
   653 	if ( modified )
       
   654 		{
       
   655 		aNewItem.Zero();
       
   656 		RDesWriteStream dws( aNewItem );
       
   657 		CleanupClosePushL( dws );
       
   658 		newItemParser->ExternalizeL( dws );
       
   659 		dws.CommitL();
       
   660 		CleanupStack::PopAndDestroy(); // dws
       
   661 		}
       
   662 
       
   663 	CleanupStack::PopAndDestroy( 4 ); // oldStream, oldItemParser, newStream, newItemParser
       
   664 	}
       
   665 
       
   666 // ------------------------------------------------------------------------------------------------
       
   667 // CNSmlDataModBase::MergeEntityL
       
   668 // Merges data from old entity to new entity.
       
   669 // ------------------------------------------------------------------------------------------------
       
   670 void CNSmlDataModBase::MergeEntityL( CVersitParser* aNewEntity, CVersitParser* aOldEntity, TBool& aModified, TBool aFieldLevel ) const
       
   671 	{
       
   672 	_DBG_FILE("CNSmlDataModBase::MergeEntityL(): begin");
       
   673 
       
   674 	// Remove all data that was not supposed to be supported by the partner but
       
   675 	// it was still sent to us.
       
   676 	StripAllNotOnPartnerListL( aNewEntity, aModified );
       
   677 	
       
   678 	if( !aFieldLevel )
       
   679 		{
       
   680 		// Remove all properties from old item that are supported by remote server.
       
   681 		// If it is field level then old this is not done.
       
   682 		StripAllOnPartnerListL( aOldEntity, aModified, ETrue );
       
   683 		CArrayPtr<CParserProperty>* mergeProps = aOldEntity->ArrayOfProperties( ETrue );
       
   684 		if( mergeProps )
       
   685 		    {
       
   686 			CleanupStack::PushL( mergeProps );
       
   687 			
       
   688 			for( TInt i = 0; i < mergeProps->Count(); i++ )
       
   689 				{
       
   690 				aNewEntity->AddPropertyL( mergeProps->At( i ), ETrue );
       
   691 				}
       
   692 			
       
   693 			CleanupStack::PopAndDestroy(); // mergeProps
       
   694 		    }
       
   695 		}
       
   696     else // Support for Field level merge
       
   697         {
       
   698         //Field level merge. Merge new item with old item. Properties of 
       
   699         //the old item are copied to new item if the new item entity does not 
       
   700         //contain certain property.
       
   701         //------------------------------------------------------------------------
       
   702         // Old                 New                          Merged                 
       
   703         //------------------------------------------------------------------------
       
   704         // BEGIN:VCARD       -> BEGIN:VCARD                 = BEGIN:VCARD 
       
   705         // VERSION:2.1       -> VERSION:2.1                 = VERSION:2.1
       
   706         // N:Smith;John      -> N:White;John                = N:White;John
       
   707         // ORG:Firm                                         = ORG:Firm
       
   708         // TITLE:Boss                                       = TITLE:Boss
       
   709         //                   -> TEL;CELL;VOICE:1234         = TEL;CELL;VOICE:1234
       
   710         // END:VCARD         -> END:VCARD                   = END:VCARD
       
   711 
       
   712         CArrayPtr<CParserProperty>* newProps = aNewEntity->ArrayOfProperties( EFalse );
       
   713         if( newProps )
       
   714             {
       
   715             CArrayPtr<CParserProperty>* oldProps = aOldEntity->ArrayOfProperties( EFalse );
       
   716 
       
   717             // Iterate through old list of properties. Add missing properties from old 
       
   718             // contact item, if some of the properties is not included in new item. 
       
   719             for( TInt i = 0; i < oldProps->Count(); ) 
       
   720                 {
       
   721                 CParserProperty* oldProperty = oldProps->At( i );
       
   722                 
       
   723                 //Check if the property is included in received vCard
       
   724                 CArrayPtr<CParserProperty>* properties = aNewEntity->PropertyL( 
       
   725                     oldProperty->Name(), oldProperty->Uid(), EFalse );
       
   726 
       
   727                 if ( !properties )
       
   728                     {
       
   729                     // New vCard does not include certain property. Copy all matching properties from 
       
   730                     // existing contact item.
       
   731                     CArrayPtr<CParserProperty>* oldProperties =
       
   732                         aOldEntity->PropertyL( oldProperty->Name(), oldProperty->Uid(), ETrue );
       
   733                     CleanupPtrArrayPushL( oldProperties );
       
   734                     
       
   735                     for ( TInt j = oldProperties->Count()-1; j >= 0; --j )
       
   736                         {
       
   737                         CParserProperty* property = oldProperties->At( j );
       
   738                         oldProperties->Delete( j );
       
   739                         CleanupStack::PushL( property );
       
   740                         aNewEntity->AddPropertyL( property, EFalse );
       
   741                         CleanupStack::Pop( property );
       
   742                         aModified = ETrue;
       
   743                         }       
       
   744                     CleanupStack::PopAndDestroy( oldProperties );
       
   745                     }
       
   746                 else
       
   747                     {
       
   748                     // If new vCard includes at least one property with same name we will not copy 
       
   749                     // any any property with same name from existing contact item.
       
   750                     delete properties;
       
   751                      ++i;
       
   752                     }
       
   753                 }
       
   754             }
       
   755 		}
       
   756 	
       
   757 	#ifdef __NSML_DEBUG__
       
   758 		CArrayPtr<CParserProperty>* props = aNewEntity->ArrayOfProperties( EFalse );
       
   759 		for( TInt i = 0; i < props->Count(); i++ )
       
   760 			{
       
   761 			TBuf8<512> b;
       
   762 			const CParserProperty* p = props->At( i );
       
   763 			b = p->Name();
       
   764 			const CArrayPtr<CParserParam>* pa = ( ( CNSmlProperty* )p )->Parameters();
       
   765 			if( pa )
       
   766 				{
       
   767 				for( TInt i2 = 0; i2 < pa->Count(); i2++ )
       
   768 					{
       
   769 					b.Append( _L8(":") );
       
   770 					b.Append( pa->At( i2 )->Name() );
       
   771 					}
       
   772 				}
       
   773 			DBG_ARGS8(_S8("CNSmlDataModBase::MergeEntityL(): %S"), &b);
       
   774 			}
       
   775 	#endif // __NSML_DEBUG__
       
   776 	_DBG_FILE("CNSmlDataModBase::MergeEntityL(): end");
       
   777 	}
       
   778 
       
   779 // End of file