phonebookengines/contactsmodel/cntplsql/src/rpplicccontactstore.cpp
branchRCL_3
changeset 20 f4a778e096c2
parent 0 e686773b3f54
equal deleted inserted replaced
19:5b6f26637ad3 20:f4a778e096c2
       
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @internalComponent
       
    19  @released
       
    20 */
       
    21 
       
    22 #include "rpplicccontactstore.h"
       
    23 #include "clplcontactproperties.h"
       
    24 #include <phbksync.h>
       
    25 
       
    26 /**
       
    27 RPplIccContactStore constructor.
       
    28 */
       
    29 RPplIccContactStore::RPplIccContactStore(CLplContactProperties& aContactProperties)
       
    30 	:
       
    31 	iProperties(aContactProperties)	
       
    32 	{
       
    33 	}
       
    34 
       
    35 
       
    36 /**
       
    37 Close the ICC contacts store.
       
    38 */
       
    39 void RPplIccContactStore::Close()
       
    40 	{
       
    41 	iTransactionOps.Close();
       
    42 	}
       
    43 
       
    44 
       
    45 /**
       
    46 Marks the start of a transaction.  If a transaction is already in progress
       
    47 leaves with KErrAlreadyExists.
       
    48 
       
    49 This method is part of the MLplTransactionManager interface.
       
    50 */
       
    51 void RPplIccContactStore::StartTransactionL()
       
    52 	{
       
    53 	// If transaction already active then leave.
       
    54 	if (iTransactionActive)
       
    55 		{
       
    56 		User::Leave(KErrAlreadyExists);
       
    57 		}
       
    58 
       
    59 	iTransactionActive = ETrue;
       
    60 	}
       
    61 
       
    62 
       
    63 /**
       
    64 Commits the current transaction.  If no transaction is in progress leaves with
       
    65 KErrNotFound.
       
    66 
       
    67 This method is part of the MLplTransactionManager interface.
       
    68 
       
    69 @param aSessionId The ID of the session that issued the request.  Used to
       
    70 prevent Phonebook Synchroniser deadlock.
       
    71 */
       
    72 void RPplIccContactStore::CommitCurrentTransactionL(TUint aSessionId)
       
    73 	{
       
    74 	// If no transaction active then leave.
       
    75 	if (!iTransactionActive)
       
    76 		{
       
    77 		User::Leave(KErrNotFound);
       
    78 		}
       
    79 
       
    80 	ExecuteTransactionL(aSessionId);
       
    81 	// Clear operation cache.
       
    82 	iTransactionOps.Reset();
       
    83 
       
    84 	iTransactionActive = EFalse;
       
    85 	}
       
    86 
       
    87 
       
    88 /**
       
    89 Rolls back the current transaction.  If no transaction is in progress then
       
    90 returns.
       
    91 
       
    92 This method is part of the MLplTransactionManager interface.
       
    93 
       
    94 @param aSessionId The ID of the session that issued the request.  Used to
       
    95 prevent Phonebook Synchroniser deadlock.
       
    96 */
       
    97 void RPplIccContactStore::RollbackCurrentTransaction(TUint aSessionId)
       
    98 	{
       
    99 	if (!iTransactionActive)
       
   100 		{
       
   101 		return;
       
   102 		}
       
   103 
       
   104 	RollbackTransactionL(aSessionId);
       
   105 	// Clear operation cache.
       
   106 	iTransactionOps.Reset();
       
   107 
       
   108 	iTransactionActive = EFalse;
       
   109 	}
       
   110 
       
   111 
       
   112 TBool RPplIccContactStore::IsTransactionActive() const 
       
   113 	{
       
   114 	return iTransactionActive;
       
   115 	}
       
   116 
       
   117 
       
   118 /**
       
   119 Creates an ICC entry for the given contact item.
       
   120 
       
   121 Transactions are handled differently when creating ICC contacts.  We need to
       
   122 actually write the ICC contact before the transaction is commited.  Update and
       
   123 Delete operations can be done at commit time.
       
   124 
       
   125 @param aItem Contact item for which to create ICC entry.
       
   126 @param aSessionId The ID of the session that issued the request.  Used to
       
   127 prevent Phonebook Synchroniser deadlock.
       
   128 */
       
   129 TContactItemId RPplIccContactStore::CreateInDbL(CContactItem& aItem, TUint aSessionId)
       
   130 	{
       
   131 	#if defined(__PROFILE_DEBUG__)
       
   132 		RDebug::Print(_L("[CNTMODEL] MTD: RPplIccContactStore::CreateInDbL"));
       
   133 	#endif 
       
   134 		
       
   135 	// Make sure the contact is a CContactICCEntry.  If it isn't then don't do
       
   136 	// anything.
       
   137 	if (aItem.Type() != KUidContactICCEntry)
       
   138 		{
       
   139 		return KNullContactId;
       
   140 		}
       
   141 
       
   142 	// If in transaction then add to cache.
       
   143 	if (iTransactionActive)
       
   144 		{
       
   145 		TIccContactOperation op(aItem, EIccContactCreate);
       
   146 		iTransactionOps.AppendL(op);
       
   147 		}
       
   148 	
       
   149 	// Perform operation.
       
   150 	CreateIccContactL(aItem, aSessionId);
       
   151 	
       
   152 	// Obtain the ID of the ICC group.
       
   153 	TContactItemId groupId = KNullContactId;
       
   154 	const CContactItemFieldSet& fieldset = aItem.CardFields();
       
   155 	const TInt n = fieldset.Find(KUidContactFieldICCPhonebook);
       
   156 	if(n!=KErrNotFound) // Is KUidContactFieldICCPhonebook field supplied?
       
   157 		{
       
   158 		TPtrC phonebookField = fieldset[n].TextStorage()->Text();
       
   159 		TLex lex(phonebookField);
       
   160 		TUid phonebookUid;
       
   161 		lex.Val(phonebookUid.iUid);
       
   162 		groupId = iProperties.ContactSynchroniserL(aSessionId).GroupIdL(phonebookUid);
       
   163 		}
       
   164 	else
       
   165 		{
       
   166 		// Client hasn't supplied the KUidContactFieldICCPhonebook field.
       
   167 		// The Phonebook Synchroniser will provide the group ID for the
       
   168 		// Global/GSM ADN phonebook group as a default.
       
   169 		groupId = iProperties.ContactSynchroniserL(aSessionId).GroupIdL(KUidIccGlobalAdnPhonebook);
       
   170 		}
       
   171 
       
   172     return groupId;	
       
   173 	}
       
   174 
       
   175 
       
   176 /**
       
   177 Validate the entry to make sure it can be read from the ICC.
       
   178 
       
   179 @param aItem Contact item to be validated for reading from the ICC.
       
   180 @param aSessionId The ID of the session that issued the request.  Used to
       
   181 prevent Phonebook Synchroniser deadlock.
       
   182 @param aIccOpenCheck ETrue if validation for open for edit should also be done.
       
   183 */
       
   184 void RPplIccContactStore::ReadL(CContactItem& aItem, TInt /*aInfoToRead*/, TUint aSessionId, TBool aIccOpenCheck) const
       
   185 	{
       
   186 	// Make sure the contact is a CContactICCEntry.  If it isn't then don't do
       
   187 	// anything.
       
   188 	if (aItem.Type() != KUidContactICCEntry)
       
   189 		{
       
   190 		return;
       
   191 		}
       
   192 	
       
   193 	ValidateIccContactL(MContactSynchroniser::ERead, aItem, aSessionId);
       
   194 
       
   195 	if(aIccOpenCheck)
       
   196 		{
       
   197 		ValidateIccContactL(MContactSynchroniser::EEdit, aItem, aSessionId);	
       
   198 		}
       
   199 	}
       
   200 
       
   201 
       
   202 /**
       
   203 Update an ICC entry using the given contact item.  If in a transaction then just
       
   204 add the operation to the cache, otherwise do the update directly.
       
   205 
       
   206 @param aNewItem The contact to be updated.
       
   207 @param aSessionId The ID of the session that issued the request.  Used to
       
   208 prevent Phonebook Synchroniser deadlock.
       
   209 */
       
   210 void RPplIccContactStore::UpdateL(CContactItem& aNewItem, TUint aSessionId)
       
   211 	{
       
   212 	// Make sure the contact is a CContactICCEntry.  If it isn't then don't do
       
   213 	// anything.
       
   214 	if (aNewItem.Type() != KUidContactICCEntry)
       
   215 		{
       
   216 		return;
       
   217 		}
       
   218 
       
   219 	// If in transaction then add to cache.
       
   220 	// Otherwise perform operation.
       
   221 	if (iTransactionActive)
       
   222 		{
       
   223 		TIccContactOperation op(aNewItem, EIccContactUpdate);
       
   224 		iTransactionOps.AppendL(op);
       
   225 		}
       
   226 	else
       
   227 	    {
       
   228         if (aNewItem.IsDeleted() && (aNewItem.AccessCount() == 0))
       
   229             {
       
   230             DeleteL(aNewItem, aSessionId);
       
   231             }
       
   232     	else
       
   233     		{
       
   234     		UpdateIccContactL(aNewItem, aSessionId);
       
   235     		}
       
   236 	    }	
       
   237 	}
       
   238 
       
   239 
       
   240 /**
       
   241 Delete the ICC entry associated with the given contact item.
       
   242 
       
   243 @param aItem Contact item whose associated ICC entry is to be deleted.
       
   244 @param aSessionId The ID of the session that issued the request.  Used to
       
   245 prevent Phonebook Synchroniser deadlock.
       
   246 */
       
   247 void RPplIccContactStore::DeleteL(const CContactItem& aItem, TUint aSessionId)
       
   248 	{
       
   249 	// Make sure the contact is a CContactICCEntry and that it can be deleted.
       
   250 	// If not then don't do anything.
       
   251 	if (aItem.Type() != KUidContactICCEntry ||
       
   252 		!const_cast<CContactItem&>(aItem).IsDeletable())
       
   253 		{
       
   254 		return;
       
   255 		}
       
   256 	DeleteIccContactL(aItem, aSessionId);
       
   257 	}
       
   258 
       
   259 
       
   260 void RPplIccContactStore::PersistorChangeTypeL(TContactItemId /*aItemId*/, TUid /*aNewType*/)
       
   261 	{
       
   262 	// Do nothing.
       
   263 	}
       
   264 
       
   265 
       
   266 /**
       
   267 Perform the operations stored in the cache.
       
   268 
       
   269 @param aSessionId The ID of the session that issued the request.  Used to
       
   270 prevent Phonebook Synchroniser deadlock.
       
   271 */
       
   272 void RPplIccContactStore::ExecuteTransactionL(TUint aSessionId)
       
   273 	{
       
   274 	for (TInt i = 0; i < iTransactionOps.Count(); i++)
       
   275 		{
       
   276 		TIccContactOperation op = iTransactionOps[i];
       
   277 		switch (op.iType)
       
   278 			{
       
   279 			case EIccContactCreate:
       
   280 				// Nothing to do since create operations are executed
       
   281 				// immediately, even in transactions.
       
   282 				break;
       
   283 			case EIccContactUpdate:
       
   284 				UpdateIccContactL(op.iContact, aSessionId);
       
   285 				break;
       
   286 			case EIccContactDelete:
       
   287 				DeleteIccContactL(op.iContact, aSessionId);
       
   288 				break;
       
   289 			default:
       
   290 				User::Leave(KErrNotSupported);
       
   291 				break;
       
   292 			}
       
   293 		}
       
   294 	}
       
   295 
       
   296 	
       
   297 /**
       
   298 Rollback the cached operations.  Only Create operations need special attention
       
   299 since we need to remove those ICC entries that were created during the
       
   300 transaction.
       
   301 
       
   302 @param aSessionId The ID of the session that issued the request.  Used to
       
   303 prevent Phonebook Synchroniser deadlock.
       
   304 
       
   305 @leave KErrNoMemory Out of memory.
       
   306 @leave KErrGeneral
       
   307 @leave [other system-wide leave codes]
       
   308 */
       
   309 void RPplIccContactStore::RollbackTransactionL(TUint aSessionId)
       
   310 	{
       
   311 	for (TInt i = 0; i < iTransactionOps.Count(); i++)
       
   312 		{
       
   313 		TIccContactOperation op = iTransactionOps[i];
       
   314 		switch (op.iType)
       
   315 			{
       
   316 			case EIccContactCreate:
       
   317 				// Delete the ICC entry.
       
   318 				DeleteIccContactL(op.iContact, aSessionId);
       
   319 				break;
       
   320 			case EIccContactUpdate:
       
   321 			case EIccContactDelete:
       
   322 				// Nothing to do.
       
   323 				break;
       
   324 			default:
       
   325 				// Give up.
       
   326 				return;
       
   327 			}
       
   328 		}
       
   329 	}
       
   330 
       
   331 
       
   332 /**
       
   333 Write a contact using the Phonebook Synchroniser.  We can call the
       
   334 UpdatePostWriteL() method right after ValidateWriteContact() because we make the
       
   335 assumption that by the time this function is called the contact item has already
       
   336 had a UID assigned to it.
       
   337 
       
   338 @param aSessionId The ID of the session that issued the request.  Used to
       
   339 prevent Phonebook Synchroniser deadlock.
       
   340 */
       
   341 void RPplIccContactStore::CreateIccContactL(CContactItem& aItem, TUint aSessionId)
       
   342 	{
       
   343 	iProperties.ContactSynchroniserL(aSessionId).UpdatePostWriteL(static_cast<CContactICCEntry&>(aItem));
       
   344 	}
       
   345 
       
   346 
       
   347 /**
       
   348 Update a contact using the Phonebook Synchroniser.
       
   349 
       
   350 @param aItem Contact item whose associated ICC entry is to be updated.
       
   351 @param aSessionId The ID of the session that issued the request.  Used to
       
   352 prevent Phonebook Synchroniser deadlock.
       
   353 */
       
   354 void RPplIccContactStore::UpdateIccContactL(CContactItem& aCurrItem, TUint aSessionId)
       
   355 	{
       
   356 	TInt ret = iProperties.ContactSynchroniserL(aSessionId).ValidateWriteContact(static_cast<CContactICCEntry&>(aCurrItem));
       
   357 	User::LeaveIfError(ret);			
       
   358 	}
       
   359 
       
   360 
       
   361 /**
       
   362 Delete a contact using the Phonebook Synchroniser.
       
   363 
       
   364 @param aItem Contact item whose associated ICC entry is to be deleted.
       
   365 @param aSessionId The ID of the session that issued the request.  Used to
       
   366 prevent Phonebook Synchroniser deadlock.
       
   367 
       
   368 @leave KErrNoMemory Out of memory.
       
   369 @leave KErrGeneral
       
   370 */
       
   371 void RPplIccContactStore::DeleteIccContactL(const CContactItem& aItem, TUint aSessionId)
       
   372 	{
       
   373 	TInt ret = iProperties.ContactSynchroniserL(aSessionId).DeleteContact(aItem.Id());
       
   374 	User::LeaveIfError(ret);	
       
   375 	}
       
   376 
       
   377 
       
   378 /**
       
   379 Validate a contact using the Phonebook Synchroniser.
       
   380 
       
   381 @param aOp Validate operation.
       
   382 @param aItem Contact item for which the operation is to be validated.
       
   383 @param aSessionId The ID of the session that issued the request.  Used to
       
   384 prevent Phonebook Synchroniser deadlock.
       
   385 */
       
   386 void RPplIccContactStore::ValidateIccContactL(MContactSynchroniser::TValidateOperation aOp,
       
   387 	CContactItem& aItem, TUint aSessionId) const
       
   388 	{
       
   389 	TInt ret = iProperties.ContactSynchroniserL(aSessionId).ValidateContact(aOp, aItem.Id());
       
   390 	User::LeaveIfError(ret);
       
   391 	}