phonebookengines/contactsmodel/cntplsql/src/cntmetadataoperation.cpp
changeset 24 0ba2181d7c28
equal deleted inserted replaced
0:e686773b3f54 24:0ba2181d7c28
       
     1 /*
       
     2 * Copyright (c) 2005-2009 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: 
       
    15 *
       
    16 */
       
    17 
       
    18 //#include <columbo.h>
       
    19 #include <cntitem.h>
       
    20 #include <cntfldst.h>
       
    21 
       
    22 #include "cntmetadataoperation.h"
       
    23 
       
    24 CCntMetadataOperation::CCntMetadataOperation(RColumboSession& aSession) 
       
    25 : CActive(EPriorityStandard), iSession(aSession), iContactId(-1)
       
    26     {
       
    27     }
       
    28 
       
    29 /**
       
    30  * Construct a new metadata operation object. Note that this object will destroy
       
    31  * itself after either save or delete operations have been called.
       
    32  * 
       
    33  * The new object will be left on the cleanup stack.
       
    34  * 
       
    35  * @param aSession Session with the metadata service.
       
    36  * @return The new metadata operation instance.
       
    37  */
       
    38 CCntMetadataOperation* CCntMetadataOperation::NewLC(RColumboSession& aSession)
       
    39     {
       
    40     CCntMetadataOperation* self = new (ELeave) CCntMetadataOperation(aSession);
       
    41     CleanupStack::PushL(self);
       
    42     self->ConstructL();
       
    43     return self;
       
    44     }
       
    45 
       
    46 /**
       
    47  * Construct a new metadata operation object. Note that this object will destroy
       
    48  * itself after either save or delete operations have been called.
       
    49  * 
       
    50  * @param aSession Session with the metadata service.
       
    51  * @return The new metadata operation instance.
       
    52  */
       
    53 CCntMetadataOperation* CCntMetadataOperation::NewL(RColumboSession& aSession)
       
    54     {
       
    55     CCntMetadataOperation* self = CCntMetadataOperation::NewLC(aSession);
       
    56     CleanupStack::Pop();
       
    57     return self;
       
    58     }
       
    59 
       
    60 /**
       
    61  * Note: upon construction, the active object is set active and waiting
       
    62  * for a completion event to destroy itself.
       
    63  */
       
    64 void CCntMetadataOperation::ConstructL()
       
    65     {
       
    66     CActiveScheduler::Add(this);
       
    67     }
       
    68 
       
    69 CCntMetadataOperation::~CCntMetadataOperation()
       
    70     {
       
    71     // (iSession is not owned)
       
    72     delete iDocument;
       
    73     delete iKey;
       
    74     }
       
    75 
       
    76 /**
       
    77  * The DoCancel() function will only delete the object in production builds.
       
    78  * If __PROFILE_DEBUG__ is defined in the persistence layer MMP file,
       
    79  * error codes will be logged should they occur.
       
    80  */
       
    81 void CCntMetadataOperation::DoCancel()
       
    82     {
       
    83     // Log that the operation is cancelled.
       
    84 #ifdef __PROFILE_DEBUG__
       
    85     _LIT(KCancelFormat, "CCntMetadataOperation::DoCancel(): Operation Cancelled: Contact ID = %d");
       
    86     RDebug::Print(KCancelFormat(), iContactId);
       
    87 #endif
       
    88     
       
    89     // Self destruct - operation cancelled.
       
    90     delete this;
       
    91     }
       
    92 
       
    93 /**
       
    94  * The RunL() function will only delete the object in production builds.
       
    95  * If __PROFILE_DEBUG__ is defined in the persistence layer MMP file,
       
    96  * error codes will be logged should they occur.
       
    97  */
       
    98 void CCntMetadataOperation::RunL()
       
    99     {
       
   100 #ifdef __PROFILE_DEBUG__
       
   101     if (iStatus.Int() != KErrNone)
       
   102         {
       
   103         _LIT(KErrorFormat, "CCntMetadataOperation::RunL(): Operation failed [Contact ID = %d] Error = %d");
       
   104         RDebug::Print(KErrorFormat(), iContactId, iStatus.Int());
       
   105         }
       
   106     else
       
   107         {
       
   108         _LIT(KErrorFormat, "CCntMetadataOperation::RunL(): Operation complete [Contact ID = %d]");
       
   109         RDebug::Print(KErrorFormat(), iContactId);
       
   110         }
       
   111 #endif // __PROFILE_DEBUG__
       
   112     
       
   113     // Self destruct - operation complete.
       
   114     delete this;
       
   115     }
       
   116 
       
   117 TInt CCntMetadataOperation::RunError(TInt aError)
       
   118     {
       
   119     // RunL() doesn't really leave, this should never happen.
       
   120     // Log but do nothing.
       
   121 #ifdef __PROFILE_DEBUG__
       
   122     _LIT(KRunErrorLog, "CCntMetadataOperation::RunError(): aError = %d");
       
   123     RDebug::Print(KRunErrorLog(), aError);
       
   124 #endif // __PROFILE_DEBUG__
       
   125     return aError;
       
   126     }
       
   127 
       
   128 /**
       
   129  * Save the contact @a aContact in the metadata service. If there is
       
   130  * already a contact entry with this ID, it will be updated. Otherwise,
       
   131  * a new contact metadata entry is added.
       
   132  * 
       
   133  * The metadata operation object will be destroyed when the operation
       
   134  * completes. Do not attempt to use this object after calling.
       
   135  * 
       
   136  * @param aContact The contact item to index for metadata.
       
   137  */
       
   138 void CCntMetadataOperation::SaveContactLD(const CContactItem& aContact)
       
   139     {
       
   140     // For logging purposes
       
   141     iContactId = aContact.Id();
       
   142     
       
   143     // Create a new generic metadata object for this contact item.
       
   144     if (iDocument)
       
   145         {
       
   146         delete iDocument;
       
   147         iDocument = NULL;
       
   148         }
       
   149     iDocument = DocumentFromContactL(aContact);
       
   150     iDocument->Store(iSession, iStatus);
       
   151     SetActive();
       
   152     }
       
   153 
       
   154 /**
       
   155  * Remove the contact described by @a aContactId from the metadata store.
       
   156  * 
       
   157  * The metadata operation object will be destroyed when the operation
       
   158  * completes. Do not attempt to use this object after calling.
       
   159  * 
       
   160  * @param aContactId The contact to be removed from the metadata service
       
   161  */
       
   162 void CCntMetadataOperation::DeleteContactLD(TInt aContactId)
       
   163     {
       
   164     // For logging purposes
       
   165     iContactId = aContactId;
       
   166     
       
   167     // Get the key and delete the document
       
   168     if (iKey)
       
   169 		{
       
   170 		delete iKey;
       
   171 		iKey = NULL;
       
   172 		}
       
   173     HBufC* iKey = ContactMetadataKeyLC(aContactId);
       
   174     CleanupStack::Pop();
       
   175     
       
   176     iSession.DeleteDocument(*iKey, iStatus);
       
   177     SetActive();
       
   178     }
       
   179 
       
   180 /**
       
   181  * Construct a new generic metadata object to represent a contact item.
       
   182  * 
       
   183  * @param aContact The contact item to encode as a generic metadata object.
       
   184  * @return The newly constructed metadata object instance.
       
   185  */
       
   186 CMetadataDocument* CCntMetadataOperation::DocumentFromContactL(const CContactItem& aContact)
       
   187     {
       
   188     CMetadataDocument* document = CMetadataDocument::NewLC();
       
   189     
       
   190     // Assign a unique key for cntmodel purposes
       
   191     HBufC* key = ContactMetadataKeyLC(aContact.Id());
       
   192     document->SetUserKeyL(*key);
       
   193     CleanupStack::PopAndDestroy(key);
       
   194     
       
   195     // Iterate through fields, and produce a metadata string for this contact
       
   196     CContactItemFieldSet& fields = aContact.CardFields();
       
   197     const TInt KFieldCount(fields.Count());
       
   198     
       
   199     if (KFieldCount > 0)
       
   200         {
       
   201         // Find out how much space we need for the metadata buffer
       
   202         TInt bufferLength(0);
       
   203         for(TInt i(0); i < KFieldCount; ++i)
       
   204             {
       
   205             CContactItemField& field = fields[i];
       
   206             if (field.StorageType() != KStorageTypeText)
       
   207                 {
       
   208                 // Can only index text, no point if text is 0 length
       
   209                 continue;
       
   210                 }
       
   211             
       
   212             // No point in indexing 0 length data
       
   213             TInt fieldLength = field.TextStorage()->Text().Length();
       
   214             if (fieldLength == 0)
       
   215                 {
       
   216                 continue;
       
   217                 }
       
   218             
       
   219             // Add field length plus the length of a space to
       
   220             // seperate it from the next field
       
   221             bufferLength += (fieldLength + 1);
       
   222             }
       
   223         
       
   224         // Allocate a buffer and add all the fields to it
       
   225         HBufC* metadata = HBufC::NewLC(bufferLength);
       
   226         TPtr bufferPtr = metadata->Des();
       
   227         
       
   228         for(TInt i(0); i < KFieldCount; ++i)
       
   229             {
       
   230             CContactItemField& field = fields[i];
       
   231             if (field.StorageType() != KStorageTypeText)
       
   232                 {
       
   233                 // Can only index text
       
   234                 continue;
       
   235                 }
       
   236             
       
   237             // No point in indexing 0 length data
       
   238             TInt fieldLength = field.TextStorage()->Text().Length();
       
   239             if (fieldLength == 0)
       
   240                 {
       
   241                 continue;
       
   242                 }
       
   243             
       
   244             TPtrC fieldContent = field.TextStorage()->Text();
       
   245             bufferPtr.Append(fieldContent);
       
   246 
       
   247             // Add a space as a seperator
       
   248             _LIT(KSpace, " ");
       
   249             bufferPtr.Append(KSpace);
       
   250             }
       
   251 
       
   252         // Add the metadta to the generic document
       
   253         document->SetMetadataL(*metadata);
       
   254         CleanupStack::PopAndDestroy(metadata);
       
   255         }
       
   256     
       
   257     CleanupStack::Pop(document);
       
   258     return document;
       
   259     }
       
   260 
       
   261 /**
       
   262  * Generate an RDNS style key to identify the metadata object for cntmodel purposes.
       
   263  * 
       
   264  * @param aContactId The contact model assigned contact ID.
       
   265  * @return A descriptor containing the new unique identifier for the document object.
       
   266  */
       
   267 HBufC* CCntMetadataOperation::ContactMetadataKeyLC(TInt aContactId)
       
   268     {
       
   269     // Key format for cntmodel entries in the metadata service
       
   270     _LIT(KKeyFormat, "com.nokia.contact.id.%d");
       
   271     
       
   272     // Allocate a big enough buffer for just the key format with
       
   273     // an integer added to the end
       
   274     HBufC* key = HBufC::NewLC(KKeyFormat().Length() + 32);
       
   275     TPtr keyPtr = key->Des();
       
   276     keyPtr.AppendFormat(KKeyFormat(), aContactId);
       
   277     
       
   278     // Leaving key on the cleanup stack
       
   279     return key;
       
   280     }
       
   281