|
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: XDM Document |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 #ifndef __XDMDOCUMENT__ |
|
22 #define __XDMDOCUMENT__ |
|
23 |
|
24 #include <e32cmn.h> |
|
25 #include <e32base.h> |
|
26 #include <XdmNamespaceContainer.h> |
|
27 |
|
28 //The supported document types = application usages |
|
29 enum TXdmDocType |
|
30 { |
|
31 EXdmDocGeneral = 0, |
|
32 EXdmTestDocType, |
|
33 EXdmPoCGroup, |
|
34 EXdmPoCUserAccessPolicy, |
|
35 EXdmDirectory, |
|
36 EXdmCapabilities, |
|
37 EXdmSharedXdm, |
|
38 EXdmRlsServices, |
|
39 EXdmResourceLists, |
|
40 EXdmIetfCommonPolicy, |
|
41 EXdmOmaCommonPolicy, |
|
42 EXdmIetfPresenceRules, |
|
43 EXdmOmaPresenceRules, |
|
44 EXdmPresContent, |
|
45 EXdmPresContentNSN |
|
46 }; |
|
47 |
|
48 //Helper class for searching documents; 16-bit |
|
49 struct SXdmAttribute16 |
|
50 { |
|
51 TPtrC iName; |
|
52 TPtrC iValue; |
|
53 }; |
|
54 |
|
55 //Helper class for searching documents; 8-bit |
|
56 struct SXdmAttribute8 |
|
57 { |
|
58 TPtrC8 iName; |
|
59 TPtrC8 iValue; |
|
60 }; |
|
61 |
|
62 //Constants |
|
63 const TInt KXdmPathSeparatorChar = 47; |
|
64 |
|
65 //Forward declarations |
|
66 class CXdmEngine; |
|
67 class MXdmOperation; |
|
68 class CXdmDocumentNode; |
|
69 class CXdmNodeAttribute; |
|
70 class CXdmOperationFactory; |
|
71 |
|
72 // CLASS DECLARATION |
|
73 class CXdmDocument : public CActive, |
|
74 public MXdmNamespaceContainer |
|
75 { |
|
76 public: // Constructors and destructor |
|
77 |
|
78 /** |
|
79 * Returns the name of this document |
|
80 * @return TPtrC The name of the document this object models |
|
81 */ |
|
82 IMPORT_C TPtrC Name() const; |
|
83 |
|
84 /** |
|
85 * Fetch data from the document this object models beginning from the |
|
86 * element the parameter points to. If the parameter is not specified, |
|
87 * the operation applies to the whole of the document. |
|
88 * |
|
89 * @param CXdmDocumentNode* The element (including its descendants) to fetch. |
|
90 * @return void |
|
91 */ |
|
92 IMPORT_C void FetchDataL( CXdmDocumentNode* aDocNode = NULL ); |
|
93 |
|
94 /** |
|
95 * Replace the document this object models |
|
96 * |
|
97 * NOTE: The name of the document MUST remain the same. This is because |
|
98 * the operation first needs to delete the old document and then |
|
99 * store the new one. The risk of creating conflicting document |
|
100 * names is far too great in case this rule is not imposed. |
|
101 * |
|
102 * @return void |
|
103 */ |
|
104 IMPORT_C void ReplaceL(); |
|
105 |
|
106 /** |
|
107 * Replace a named element in the document this object models |
|
108 * |
|
109 * NOTE: Both elements MUST have a common parent element, |
|
110 * which, in effect, must be the element this document |
|
111 * model points to. Also note that the operation will |
|
112 * fail in case the "aOldNode" does not exist in the document. |
|
113 * |
|
114 * @param CXdmDocumentNode* The element to replace |
|
115 * @param CXdmDocumentNode* The replacing element |
|
116 * @return void |
|
117 */ |
|
118 IMPORT_C void ReplaceL( CXdmDocumentNode* aOldNode, |
|
119 CXdmDocumentNode* aNewNode ); |
|
120 |
|
121 /** |
|
122 * Insert the node identified by the parameter. Note that this |
|
123 * method cannot be applied to complete documents. Thus the method |
|
124 * will fail in case the parameter is NULL. If the client needs |
|
125 * to a) add b) replace a document, it needs to do this through |
|
126 * the AppendL() or the ReplaceL() method. |
|
127 * |
|
128 * NOTE: The operation will fail in case the element identified |
|
129 * by the aDocNode parameter already exists in the document. |
|
130 * XDM Engine does not make assumptions in this regard; it |
|
131 * does not, for instance, change some aspects of the |
|
132 * request in order to turn it into a valid insert operation. |
|
133 * Instead, it will re-read the whole document and retry the |
|
134 * insert operation. If the operation still fails, the engine |
|
135 * reports the failure that occurred while performing the |
|
136 * operation. In the latter case, the client can get a hold |
|
137 * of the error report document, provided that the used |
|
138 * protocol supports the feature and that the server included |
|
139 * the document in the response, by fetching the root node of |
|
140 * the error document through ErrorRoot() method. |
|
141 * |
|
142 * @param CXdmDocumentNode* The element (including its descendants) to insert |
|
143 * @return void |
|
144 */ |
|
145 IMPORT_C void InsertL( CXdmDocumentNode* aDocNode ); |
|
146 |
|
147 /** |
|
148 * Append data to the document this object models beginning from the |
|
149 * element the parameter points to. If the parameter is not specified, |
|
150 * the operation applies to the whole of the document. |
|
151 * |
|
152 * NOTE: This is a "blind insert"; no guarantees can be given |
|
153 * as to the success or failure of the operation, since |
|
154 * it includes no checking for existence of the resource |
|
155 * that is to be appended/inserted. It is also worth noticing |
|
156 * that this method may effectively turn into a replace |
|
157 * operation in case the method is invoked on a document that |
|
158 * already exists in the storage endpoint. |
|
159 * |
|
160 * @param CXdmDocumentNode* The element (including its descendants) to append. |
|
161 * @return void |
|
162 */ |
|
163 IMPORT_C void AppendL( CXdmDocumentNode* aDocNode = NULL ); |
|
164 |
|
165 /** |
|
166 * Delete data from the document this object models beginning from the |
|
167 * element the parameter points to. If the parameter is not specified, |
|
168 * the operation applies to the whole of the document. |
|
169 * |
|
170 * @param CXdmDocumentNode* The element (including its descendants) to delete. |
|
171 * @return void |
|
172 */ |
|
173 IMPORT_C void DeleteDataL( CXdmDocumentNode* aDocNode = NULL ); |
|
174 |
|
175 /** |
|
176 * Search for nodes which match the specified name & attributes |
|
177 * |
|
178 * @param CXdmDocumentNode& The node to search for |
|
179 * @param RPointerArray& On completion, contains the nodes |
|
180 * that were found, if any. |
|
181 * @return TInt KErrNotFound if no matching nodes are found. |
|
182 * Otherwise indicates the number of nodes found |
|
183 */ |
|
184 IMPORT_C TInt Find( const CXdmDocumentNode& aTargetNode, |
|
185 RPointerArray<CXdmDocumentNode>& aResultArray ) const; |
|
186 |
|
187 /** |
|
188 * Search for nodes which match the specified name & attributes |
|
189 * |
|
190 * @param TDesC& The name of the node to search for |
|
191 * @param RPointerArray& On completion, contains the nodes |
|
192 * that were found, if any. |
|
193 * @return TInt KErrNotFound if no matching nodes are found. |
|
194 * Otherwise indicates the number of nodes found |
|
195 */ |
|
196 IMPORT_C TInt Find( const TDesC& aNodeName, |
|
197 RPointerArray<CXdmDocumentNode>& aResultArray ) const; |
|
198 |
|
199 /** |
|
200 * Search for attributes which match the specified name |
|
201 * |
|
202 * @param TDesC& The name of the attribute to search for |
|
203 * @param RPointerArray& On completion, contains the nodes |
|
204 * that were found, if any. |
|
205 * @return TInt KErrNotFound if no matching nodes are found. |
|
206 * Otherwise indicates the number of nodes found |
|
207 */ |
|
208 IMPORT_C TInt Find( const TDesC& aAttributeName, |
|
209 RPointerArray<CXdmNodeAttribute>& aResultArray ) const; |
|
210 |
|
211 /** |
|
212 * Search for nodes which match the specified name & attributes |
|
213 * |
|
214 * @param TDesC& The name of the node to search for |
|
215 * @param RPointerArray& On completion, contains the nodes |
|
216 * that were found, if any. |
|
217 * @param RPointerArray& The attribute names & values that a |
|
218 matching node must have. |
|
219 * @return TInt KErrNotFound if no matching nodes are found. |
|
220 * Otherwise indicates the number of nodes found |
|
221 */ |
|
222 IMPORT_C TInt Find( const TDesC& aNodeName, |
|
223 RPointerArray<CXdmDocumentNode>& aResultArray, |
|
224 const RPointerArray<SXdmAttribute16>& aAttributeArray ) const; |
|
225 |
|
226 /** |
|
227 * Comparison operator |
|
228 * |
|
229 * @param CXdmDocument& The document to compare to |
|
230 * @return TBool Are the contents of the two identical |
|
231 */ |
|
232 IMPORT_C TBool operator==( CXdmDocument& aDocument ) const; |
|
233 |
|
234 /** |
|
235 * Remove an element from the document model |
|
236 * |
|
237 * NOTE: This method cannot be used with document models that |
|
238 * only target a fragment of the document; in practise |
|
239 * this means that if the client has constructed a node |
|
240 * using DocumentSubsetL(), this method leaves with KErrGeneral. |
|
241 * A document subset cannot be treated as an actual document |
|
242 * since only a fraction of the elements and their dependencies |
|
243 * in the document is known. The client must have the whole |
|
244 * document at its disposal in order to be properly able to |
|
245 * make use of this method. |
|
246 * |
|
247 * @param CXdmDocumentNode* The node to be removed |
|
248 * @return void |
|
249 */ |
|
250 IMPORT_C void RemoveFromModelL( CXdmDocumentNode* aChileNode ); |
|
251 |
|
252 /** |
|
253 * Append an element to the document model |
|
254 * |
|
255 * NOTE: This method cannot be used with document models that |
|
256 * only target a fragment of the document; in practise |
|
257 * this means that if the client has constructed a node |
|
258 * using DocumentSubsetL(), this method leaves with KErrGeneral. |
|
259 * A document subset cannot be treated as an actual document |
|
260 * since only a fraction of the elements and their dependencies |
|
261 * in the document is known. The client must have the whole |
|
262 * document at its disposal in order to be properly able to |
|
263 * make use of this method. |
|
264 * |
|
265 * @param The next node in the list |
|
266 * @return void |
|
267 */ |
|
268 IMPORT_C void AppendToModelL( CXdmDocumentNode* aNewNode, |
|
269 CXdmDocumentNode* aParentNode ); |
|
270 |
|
271 /** |
|
272 * Replace an element in the document model |
|
273 * |
|
274 * NOTE: This method cannot be used with document models that |
|
275 * only target a fragment of the document; in practise |
|
276 * this means that if the client has constructed a node |
|
277 * using DocumentSubsetL(), this method leaves with KErrGeneral. |
|
278 * A document subset cannot be treated as an actual document |
|
279 * since only a fraction of the elements and their dependencies |
|
280 * in the document is known. The client must have the whole |
|
281 * document at its disposal in order to be properly able to |
|
282 * make use of this method. |
|
283 * |
|
284 * @param CXdmDocumentNode The new node |
|
285 * @param CXdmDocumentNode The old (target) node |
|
286 * @return void |
|
287 */ |
|
288 IMPORT_C void ReplaceInModelL( CXdmDocumentNode* aNewNode, |
|
289 CXdmDocumentNode* aTargetNode ); |
|
290 |
|
291 /** |
|
292 * Return a subset of the document this object models. |
|
293 * For instance, if the whole (physical) document is |
|
294 * the following: |
|
295 * |
|
296 * <root> |
|
297 * <element1> |
|
298 * <child1> |
|
299 * <leaf1>Foo</leaf1> |
|
300 * </child1> |
|
301 * </element1> |
|
302 * </root> |
|
303 * |
|
304 * calling this method with the parameter "root/element1/child1" |
|
305 * would make this document model model the subset |
|
306 * |
|
307 * <child1> |
|
308 * <leaf1>Foo</leaf1> |
|
309 * </child1> |
|
310 * |
|
311 * It is important to understand that, after calling this method, |
|
312 * the document model only models the document starting from the |
|
313 * node the method returns. The client may traverse the document |
|
314 * all the way to the root node and back, but the way from the root |
|
315 * node to the node this method returns should be regarded merely |
|
316 * as a "path" of elements that has no real content. |
|
317 * |
|
318 * A prime use case for this method is one in which the structure |
|
319 * of the document the client application wants to operate on is |
|
320 * well-known; a typical example would be an XDM directory document. |
|
321 * The schema for this application usage is very simple: the root |
|
322 * element is <xcap-directory> that has a collection of <folder> |
|
323 * elements as its children. Each <folder> element has a mandatory |
|
324 * "auid" parameter that identifies the type of documents that |
|
325 * particular folder contains. Therefore, a client application has |
|
326 * all the necessary information it needs to have in order to be |
|
327 * able to carry out a fetch for a document subset (one folder): |
|
328 * |
|
329 * _LIT( KNodePath, "xcap-directory/folder" ); |
|
330 * CXdmDocumentNode* node = iDirectoryDoc->DocumentSubsetL( KNodePath ); |
|
331 * CleanupStack::PushL( node ); |
|
332 * CXdmNodeAttribute* auid = node->CreateAttributeL( _L( "auid" ) ); |
|
333 * CleanupStack::PushL( auid ); |
|
334 * auid->SetAttributeValueL( _L( "My document type" ) ); |
|
335 * iDirectoryDoc->FetchDataL( node ); |
|
336 * CleanupStack::Pop( 2 ); //auid, node |
|
337 * |
|
338 * In this particular case, even after the fetch operation is |
|
339 * complete, the <xcap-directory> element in this document model |
|
340 * would not be a real element, a genuine part of the document, but, |
|
341 * rather, a "virtual" node on the way to the element that is of |
|
342 * real interest to the client application. |
|
343 * |
|
344 * Also note that the instance of CXdmDocument on which this subset |
|
345 * has been created, cannot be used as a container for a whole |
|
346 * document until ResetSubset() has been called. |
|
347 * |
|
348 * The incoming parameter MUST separate each step to the |
|
349 * target element with a slash character ('/'). |
|
350 * |
|
351 * @param TDesC8& The path to the target element |
|
352 * @return CXdmDocumentNode* |
|
353 */ |
|
354 IMPORT_C CXdmDocumentNode* DocumentSubsetL( const TDesC& aNodePath ); |
|
355 |
|
356 /* |
|
357 * Reset the document subset. |
|
358 * |
|
359 * See the comments to DocumentSubsetL method for details. |
|
360 * @return void |
|
361 */ |
|
362 IMPORT_C virtual void ResetSubset(); |
|
363 |
|
364 /** |
|
365 * Destructor. |
|
366 */ |
|
367 IMPORT_C ~CXdmDocument(); |
|
368 |
|
369 public: // New functions |
|
370 |
|
371 /** |
|
372 * Return the type of this document |
|
373 * |
|
374 * @return TXdmDocType The type of the document |
|
375 */ |
|
376 virtual TXdmDocType DocumentType() const = 0; |
|
377 |
|
378 /** |
|
379 * Construct an "anonymous" entry point for this document. |
|
380 * This node effectively becomes the root of this document. |
|
381 * |
|
382 * @return CXdmDocumentNode* Document root |
|
383 */ |
|
384 virtual CXdmDocumentNode* CreateRootL() = 0; |
|
385 |
|
386 /** |
|
387 * Return the root element of this document |
|
388 * |
|
389 * NOTE: The returning node may or may not contain any data, |
|
390 * since, in the case that this document model does not |
|
391 * have content yet, the element is a simple "entry point" |
|
392 * to the whole document. Thus, for instance, if the client |
|
393 * application requests the XDM Engine to fetch a particular |
|
394 * document, the root element points to nothing until the |
|
395 * request has been completed. |
|
396 * |
|
397 * Also note that in case the client has created a document |
|
398 * subset using the DocumentSubsetL() method, this method |
|
399 * will return NULL, since the document is not traversable |
|
400 * from the root; it, by definition, represents only a subset |
|
401 * of this document. In case of a document subset, the path from |
|
402 * the root node to the target node should be considered a simple |
|
403 * linked list that does not necessarily contain all children |
|
404 * for any of the nodes in between. |
|
405 * |
|
406 * @return CXdmDocumentNode* The root element of the document |
|
407 */ |
|
408 virtual CXdmDocumentNode* DocumentRoot() const = 0; |
|
409 |
|
410 /* |
|
411 * Reset the contents of this document model. |
|
412 * |
|
413 * This method comes into play when client wants to reuse an instance |
|
414 * of this class for, for instance, construction of different content. |
|
415 * Other properties, such as name and the type of the document |
|
416 * do not change. |
|
417 * |
|
418 * @return void |
|
419 */ |
|
420 virtual void ResetContents() = 0; |
|
421 |
|
422 /** |
|
423 * Return the currently last node in the path. |
|
424 * NOTE: Only works with document subsets! |
|
425 * |
|
426 * @return CXdmDocumentNode* |
|
427 */ |
|
428 virtual CXdmDocumentNode* CurrentExtent() const = 0; |
|
429 |
|
430 /** |
|
431 * Return the time stamp for this document |
|
432 * |
|
433 * @return TTime Time stamp |
|
434 */ |
|
435 virtual TTime TimeStamp() const = 0; |
|
436 |
|
437 /** |
|
438 * Return an error document for a failed update |
|
439 * |
|
440 * NOTE: The returning object will be zero in case |
|
441 * the used protocol does not support this feature. |
|
442 * |
|
443 * @return CXdmDocument* The error document |
|
444 */ |
|
445 virtual CXdmDocumentNode* ErrorRoot() = 0; |
|
446 |
|
447 protected: |
|
448 |
|
449 /** |
|
450 * Append an element to the path identifying the |
|
451 * the current document subset |
|
452 * |
|
453 * @param TDesC& The path part to append |
|
454 * @return void |
|
455 */ |
|
456 virtual void AppendPathPartL( const TDesC& aString ) = 0; |
|
457 |
|
458 private: |
|
459 |
|
460 /** |
|
461 * Empty the operation queue |
|
462 */ |
|
463 void EmptyOperationQueue(); |
|
464 |
|
465 /** |
|
466 * Find attributes by name |
|
467 * |
|
468 * @param CXdmDocumentNode* The node to search from |
|
469 * @param TDesC& The name of the attributes to search for |
|
470 * @param RPointerArray& On completion, contains the results |
|
471 * @return TInt The number of attributes found |
|
472 */ |
|
473 TInt DoFindAttributes( CXdmDocumentNode* aNode, |
|
474 const TDesC& aAttributeName, |
|
475 RPointerArray<CXdmNodeAttribute>& aResultArray ) const; |
|
476 |
|
477 private: //Methods which need to be accessible from the CXdmEngine |
|
478 //but NOT from the client application => friend class |
|
479 |
|
480 /** |
|
481 * Start updating the document |
|
482 * @param TRequestStatus& The status of the request |
|
483 * @return void |
|
484 */ |
|
485 virtual void StartUpdateL() = 0; |
|
486 |
|
487 /** |
|
488 * Cancel a document update |
|
489 * @param TRequestStatus& The status of the request |
|
490 * @return void |
|
491 */ |
|
492 virtual void CancelUpdate() = 0; |
|
493 |
|
494 /** |
|
495 * Save the client's request status |
|
496 * @param TRequestStatus& The status of the request |
|
497 * @return void |
|
498 */ |
|
499 virtual void SaveClientStatus( TRequestStatus& aClientStatus ) = 0; |
|
500 |
|
501 protected: |
|
502 |
|
503 /** |
|
504 * By default Symbian OS constructor is private. |
|
505 * @return void |
|
506 */ |
|
507 IMPORT_C void BaseConstructL( TInt aOperationFactoryUid, |
|
508 const TDesC& aDocumentName ); |
|
509 |
|
510 /** |
|
511 * By default Symbian OS constructor is private. |
|
512 * @return void |
|
513 */ |
|
514 IMPORT_C void BaseConstructL( TInt aOperationFactoryUid, |
|
515 const TDesC8& aDocumentName ); |
|
516 |
|
517 /** |
|
518 * C++ constructor is private. |
|
519 */ |
|
520 IMPORT_C CXdmDocument( CXdmEngine& aXdmEngine ); |
|
521 |
|
522 protected: //Data |
|
523 |
|
524 TBool iDocSubset; |
|
525 HBufC* iDocumentName; |
|
526 TRequestStatus* iClientStatus; |
|
527 TTime iTimeStamp; |
|
528 CXdmEngine& iXdmEngine; |
|
529 friend class CXdmEngine; |
|
530 RPointerArray<MXdmOperation> iChangeRequests; |
|
531 CXdmOperationFactory* iOperationFactory; |
|
532 |
|
533 private: // Data |
|
534 }; |
|
535 |
|
536 #endif //__XDMDOCUMENT__ |
|
537 |
|
538 // End of File |