Changed zouba directory heirarchy.
[ptas] / zouba / wrt / preview / script / lib / sapi / Contact.js
1 /**
2  * Contact.js
3  * 
4  * Nokia Web Runtime Service API emulation 
5  * WRT v1.1
6  * 
7  * Copyright 2009 Nokia Corporation. All rights reserved.
8 */
9
10  
11 (function(){
12         
13         var provider = 'Service.Contact' ,
14                 Interface = 'IDataSource';
15
16         /**
17          * Contact service
18          */
19         var ContactService = function(){
20                 this.GetList    = __GetList;
21                 this.Add                = __Add;
22                 this.Delete     = __Delete;
23                 this.Import     = __Import;
24                 this.Export     = __Export;
25                 this.Organise   = __Organise;
26                 this.Cancel     = __Cancel;
27         }
28
29         device.implementation.extend(provider, Interface, new ContactService() );
30
31
32         /******************************************************/        
33         /******************************************************/        
34         /******************************************************/        
35
36         var     context = device.implementation.context,
37                 _t = context._t,
38                 method = '',
39                 result = false,
40                 DBase = null;
41         
42         /**
43          * Contact: GetList
44          * @param {Object} criteria
45          * @param {Function} [callback] function for async call (optional)
46          */
47         function __GetList(criteria, callback){
48
49                 if ((result = validator.apply('GetList', arguments)) !== false)
50                         return result; 
51         
52                 if (!/^(Contact|Group|Database)$/i.test(criteria.Type))
53                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badType);
54         
55                 if (typeof callback == 'function') {
56                         return context.callAsync(this, arguments.callee, criteria, callback);
57                 }
58
59                 var returnValue = [], 
60                         match = null,
61                         filter = criteria.Filter || null;
62  
63                 DBase = context.getData(provider);
64
65                 // Type = Database
66                 if (/Database/i.test(criteria.Type)){
67                         returnValue = DBase.Database;
68                 } 
69                 // Type = Group
70                 else if (/Group/i.test(criteria.Type)){
71                         // filter by id
72                         if (filter && filter.id) {
73                                 returnValue = findById(DBase.Group, filter.id);
74                                 if (returnValue.length == 0)
75                                         return error(device.implementation.ERR_NOT_FOUND);
76                         }
77                         // return all groups 
78                         else {
79                                 returnValue = DBase.Group;
80                         }
81                 }                               
82                 // Type = Contact
83                 else if (/Contact/i.test(criteria.Type)){
84
85                         // filter by id
86                         if (filter && filter.id) {
87                                 returnValue = findById(DBase.Contact, filter.id); 
88                                 if (returnValue.length == 0)
89                                         return error(device.implementation.ERR_NOT_FOUND);
90                         }
91                         // return all contacts 
92                         else {
93                                 returnValue = DBase.Contact;
94                         }
95
96                         // unsupported filters 
97                         if (filter 
98                                 && (match = context.keys(filter).join().match(/SearchVal|DBUri/ig)) ) {
99                                 context.notify(_t('%s:: GetList : filter %s not implemented in preview').arg(provider, match.join()));
100                         }
101                         // unsupported sort                     
102                         if (criteria.Sort) { 
103                                 context.notify(_t('%s:: GetList : sort not implemented in preview').arg(provider));
104                         }
105                 }
106                 return context.Result(context.Iterator(returnValue));
107         }
108                         
109         /**
110          * Contact: Add
111          * @param {Object} criteria
112          * @param {Function} [callback] function for async call (optional)
113          */
114         function __Add(criteria, callback){
115
116                 if ((result = validator.apply('Add', arguments)) !== false)
117                         return result; 
118                 
119                 if (!/^(Contact|Group)$/i.test(criteria.Type))
120                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badType2);
121
122                 if (typeof callback == 'function') {
123                         return context.callAsync(this, arguments.callee, criteria, callback);
124                 }
125
126                 DBase = context.getData(provider);
127                 var Data = criteria.Data,
128                         item;
129
130                 // unsupported!                 
131                 if (Data.DBUri) {
132                         context.notify(_t('%s:: Add : Data.DBUri not implemented in preview').arg(provider));
133                 }
134
135                 // Type = Group
136                 if (/Group/i.test(criteria.Type)){
137
138                         if (!Data.GroupLabel)
139                                 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.missingGroupLabel);
140
141                         // update
142                         if (Data.id) {
143                                 returnValue = findById(DBase.Group, Data.id); 
144                                 if (returnValue.length == 0)
145                                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE);
146                                 
147                                 returnValue[0].GroupLabel = Data.GroupLabel;
148                                 //@todo: group contents!?
149                         }
150                         // new
151                         else {
152                                 item = context.extend({}, Data); 
153                                 item.id = String(context.getUniqueID());
154                                 DBase.Group.push(item);
155                         }
156                 } 
157                 // Type = Contact
158                 else {
159                         // update
160                         if (Data.id) {
161                                 returnValue = findById(DBase.Contact, Data.id); 
162                                 if (returnValue.length == 0)
163                                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE);
164                                 
165                                 context.extend(returnValue[0], Data); 
166                         }
167                         // new
168                         else {
169                                 item = context.extend({}, Data); 
170                                 item.id = String(context.getUniqueID());
171                                 DBase.Contact.push(item);
172                         }
173                 } 
174                 // return success
175                 return error(device.implementation.ERR_SUCCESS);
176         }
177                         
178
179         /**
180          * Contact: Delete
181          * @param {Object} criteria
182          * @param {Function} [callback] function for async call (optional)
183          */
184         function __Delete(criteria, callback){
185                 
186                 if ((result = validator.apply('Delete', arguments)) !== false)
187                         return result; 
188
189                 if (!/^(Contact|Group)$/i.test(criteria.Type))
190                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badType2);
191
192                 var Data = criteria.Data;
193                 if (!Data.IdList)
194                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingIdList);
195                 if (typeof Data.IdList != 'object')
196                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badIdList);
197                 
198                 DBase = context.getData(provider);
199                 var type = criteria.Type;
200
201                 // unsupported!                 
202                 if (Data.DBUri) {
203                         context.notify(_t('%s:: Delete : Data.DBUri not implemented in preview').arg(provider));
204                 }
205
206                 if (typeof callback == 'function') {
207                         return context.callAsync(this, arguments.callee, criteria, callback);
208                 }
209
210                 // for both Group & Contact:
211                 var i,j,id,item;
212                 for (j in Data.IdList) {
213                         id = Data.IdList[j];
214                         for (i in DBase[type]) {
215                                 item = DBase[type][i];
216                                 if (id == item.id) {
217                                         DBase[type].splice(i, 1);
218                                 }
219                         }
220                 }
221                 // return success
222                 return error(device.implementation.ERR_SUCCESS);                                
223         }
224                         
225
226         /**
227          * Contact: Import
228          * @param {Object} criteria
229          * @param {Function} [callback] function for async call (optional)
230          */
231         function __Import(criteria, callback){
232
233                 if ((result = validator.apply('Import', arguments)) !== false)
234                         return result; 
235
236                 if (!/^(Contact)$/i.test(criteria.Type))
237                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badType3);
238
239                 var Data = criteria.Data;
240                 if (!Data.SourceFile)
241                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingSourceFile);
242
243                 if (typeof callback == 'function') {
244                         return context.callAsync(this, arguments.callee, criteria, callback);
245                 }
246
247                 context.notify(_t('%s:: Import : not implemented in preview.').arg(provider));
248                 return error(device.implementation.ERR_SUCCESS);                
249         }
250                         
251
252         /**
253          * Contact: Export
254          * @param {Object} criteria
255          * @param {Function} [callback] function for async call (optional)
256          */
257         function __Export(criteria, callback){
258
259                 if ((result = validator.apply('Export', arguments)) !== false)
260                         return result; 
261
262                 if (!/^(Contact)$/i.test(criteria.Type))
263                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badType4);
264
265                 var Data = criteria.Data;
266                 if (!Data.DestinationFile)
267                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingDestinationFile);
268
269                 if (!Data.id)
270                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingId);
271
272                 if (typeof callback == 'function') {
273                         return context.callAsync(this, arguments.callee, criteria, callback);
274                 }
275
276                 context.notify(_t('%s:: Export : not implemented in preview.').arg(provider));
277                 return error(device.implementation.ERR_SUCCESS);                
278         }
279                         
280
281         /**
282          * Contact: Organise
283          * @param {Object} criteria
284          * @param {Function} [callback] function for async call (optional)
285          */
286         function __Organise(criteria, callback){
287
288                 if ((result = validator.apply('Organise', arguments)) !== false)
289                         return result; 
290
291                 if (!/^(Group)$/i.test(criteria.Type))
292                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.badType5);
293
294                 var Data = criteria.Data;
295                 if (!Data.id)
296                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingId2);
297
298                 if (!Data.IdList)
299                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingIdList);
300
301                 if (typeof Data.IdList != 'object')
302                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badIdList);
303
304                 if (!/^(Associate|Disassociate)$/i.test(criteria.OperationType))
305                         return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badOperationType);
306
307                 if (typeof callback == 'function') {
308                         return context.callAsync(this, arguments.callee, criteria, callback);
309                 }
310
311                 context.notify(_t('%s:: Organise : not implemented in preview.').arg(provider));
312                 return error(device.implementation.ERR_SUCCESS);                
313         }
314                         
315
316         /**
317          * Contact: Cancel
318          * @param {Object} criteria
319          */
320         function __Cancel(criteria){
321                 method = 'Cancel';
322                 if (!criteria || !criteria.TransactionID)
323                         return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.missingTID);
324                 
325                 clearTimeout(criteria.TransactionID);
326                 return context.ErrorResult(device.implementation.ERR_SUCCESS);
327         }
328
329         
330         /*******************************
331          * helper functions
332          *******************************/
333         
334         function error(code, msg /*, args...*/){
335
336                 var args = ['Contacts',method].concat([].slice.call(arguments,2));
337                 msg = msg ? _t().arg.apply(msg,args) : undefined;
338                 return context.ErrorResult(code, msg);
339         }
340
341         /**
342          * validate common input arguments
343          * 'this' is string (object) name of calling function
344          * 
345          * @param {arguments} arguments of calling function
346          * @return {Result} Result object if error, false if no error.
347          */
348         function validator() {
349                 method = ''+this;
350                 var     failed = false,
351                         criteria = arguments[0] || false;
352                         
353                 if (!criteria || typeof criteria != 'object' || typeof criteria.Type == 'undefined')
354                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType, method);
355
356                 if (method == 'GetList') return failed;
357
358                 var Data = criteria.Data || false; 
359                 if (!Data)
360                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingData, method);
361                 if (typeof Data != 'object')
362                         return error(device.implementation.ERR_MISSING_ARGUMENT, msg.badData);
363                  
364                 return failed;
365         }
366
367
368         function findById(dbase, id){
369                 var result = [];
370                 for (var i in dbase) {
371                         if (id == dbase[i]['id']) {
372                                 result.push(dbase[i]);
373                         }
374                 }
375                 return result;
376         }
377
378         /** 
379          * error messages
380          * order of %s args: Service name, method name, parameter name 
381          */
382         var msg = {
383                 missingType             : '%s : %s : Type is Missing',
384                 badType                 : '%s: %s : Invalid value for Type, Must be Contact/Group/Database',
385                 badType2                : '%s : %s : Invalid Type, must be Contact/Group',
386                 badType3                : '%s : %s : Invalid Type,it must be Contact',
387                 badType4                : '%s : %s : Invalid Type, it must be Contact',
388                 badType5                : '%s : %s : Invalid Content Type, It must be Group',
389                 badOperationType: '%s : %s : Invalid Operation Type',
390                 missingGroupLabel: '%s : %s : Group Label is Missing',
391                 missingTID              : 'Contact : Cancel : TransactionID is missing',        // not 'Contacts'!!
392                 badAsync                : '%s : %s : Invalid async parameters',
393                 missingData             : '%s : %s : %s data Missing',
394                 badData                 : '%s : %s : Invalid Type of Data , Map is required',
395                 missingIdList   : '%s : %s : List of Ids is missing',
396                 badIdList               : '%s : %s : Type of IdList is wrong, List is required',
397                 missingSourceFile: '%s : %s : Import Source Filename is Missing',
398                 missingDestinationFile: '%s : %s : Export Destination Filename is Missing',
399                 missingId               : '%s : %s : Contact Id to be exported is missing',
400                 missingId2              : '%s : %s : GroupId is missing',
401                 is_missing              : '%s : %s : %s is missing',
402                 is_invalid              : '%s : %s : %s is invalid'
403         };
404                 
405
406 }) ()
407