|
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 |