4 * Nokia Web Runtime Service API emulation
7 * Copyright 2009 Nokia Corporation. All rights reserved.
13 var provider = 'Service.Calendar' ,
14 Interface = 'IDataSource';
19 var CalendarService = function(){
20 this.GetList = __GetList;
22 this.Delete = __Delete;
23 this.Import = __Import;
24 this.Export = __Export;
25 this.Cancel = __Cancel;
26 this.RequestNotification = __RequestNotification;
29 device.implementation.extend(provider, Interface, new CalendarService() );
32 /******************************************************/
33 /******************************************************/
34 /******************************************************/
36 var context = device.implementation.context,
41 default_calendar = 'C:Calendar';
45 * @param {Object} criteria
47 function __GetList(criteria){
48 if ((result = validator.apply('GetList', arguments)) !== false)
53 filter = criteria.Filter || null;
55 DBase = context.getData(provider);
58 if (!/CalendarEntry/i.test(criteria.Type)){
59 var cals = [default_calendar];
60 if (filter && filter.DefaultCalendar === false)
61 cals = context.keys(DBase)
66 // Type = CalendarEntry
67 var cal = default_calendar;
68 if (filter && filter.CalendarName)
69 cal = filter.CalendarName;
72 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badCalendar);
74 // filter by id or LocalId
75 if (filter && (filter.id || filter.LocalId)) {
76 var which = filter.id ? 'id' : 'LocalId',
79 for (var i in DBase[cal]) {
80 if (id == DBase[cal][i][which]) {
81 returnValue.push(DBase[cal][i]);
86 else if (filter && filter.Type && !/IncludeAll/i.test(filter.Type)) {
87 for (var i in DBase[cal]) {
88 // match on type is case insensitive
89 if (filter.Type.toLowerCase() == DBase[cal][i].Type.toLowerCase()) {
90 returnValue.push(DBase[cal][i]);
94 // unsupported filters
96 && (match = context.keys(filter).join().match(/StartRange|EndRange|SearchText/ig)) ) {
97 context.notify(_t('%s:: GetList : filter %s not implemented in preview').arg(provider, match.join()));
101 returnValue = DBase[cal];
105 return context.Result(context.Iterator(returnValue));
110 * @param {Object} criteria
112 function __Add(criteria){
113 if ((result = validator.apply('Add', arguments)) !== false)
116 var Item = criteria.Item || false;
118 DBase = context.getData(provider);
121 if (!/CalendarEntry/i.test(criteria.Type)){
123 if (!Item || !Item.CalendarName)
124 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.missingCalendar);
126 var cal = Item.CalendarName;
128 return error(device.implementation.ERR_ENTRY_EXISTS);
131 // @todo: validate calendar name <drive>:<name>
132 // return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badCalendar);
134 // create new calendar
135 device.implementation.loadData(provider, cal, []);
136 return error(device.implementation.ERR_SUCCESS);
139 // Type = CalendarEntry
142 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_missing, 'Item');
144 var cal = Item.CalendarName || default_calendar;
146 // if calendar doesn't exist and it's the default, create it
147 if (!(cal in DBase) && cal == default_calendar)
148 device.implementation.loadData(provider, cal, []);
151 return error(device.implementation.ERR_NOT_FOUND);
153 // update existing item?
154 if ('LocalId' in Item) {
156 if (!Item.LocalId && Item.LocalId !== 0)
157 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'LocalId');
159 if ('InstanceStartTime' in Item)
160 context.notify(_t('%s:: Add : InstanceStartTime not implemented in preview.').arg(provider));
165 // search for and update item
167 for (var i in DBase[cal]) {
168 var entry = DBase[cal][i];
169 if (entry.LocalId == Item.LocalId) {
170 context.extend(entry, Item);
177 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'LocalId');
181 // generate new id and localId
182 // -- in calendar id's are string!
183 Item.id = String(context.getUniqueID());
184 Item.LocalId = String(context.getUniqueID());
185 DBase[cal].push(Item);
189 return context.Result(Item.id, device.implementation.ERR_SUCCESS);
195 * @param {Object} criteria
196 * @param {function} callback function for async call (optional - valid only for CalendarEntry)
198 function __Delete(criteria, callback){
200 if ((result = validator.apply('Delete', arguments)) !== false)
203 var Data = criteria.Data || false;
204 if (!Data || typeof Data != 'object')
205 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Data');
207 // only sync call supported for Calendar
208 if (!/CalendarEntry/i.test(criteria.Type) && typeof callback == 'function')
209 return error(device.implementation.ERR_SERVICE_NOT_SUPPORTED, msg.noAsync);
211 DBase = context.getData(provider);
212 var cal = Data.CalendarName || default_calendar;
214 return error(device.implementation.ERR_NOT_FOUND);
217 if (!/CalendarEntry/i.test(criteria.Type)) {
218 // CalendarName is mandatory
219 if (!Data.CalendarName)
220 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_missing, 'CalendarName');
226 // Type = CalendarEntry
228 if (!context.keys(Data).join().match(/IdList|LocalIdList|DeleteAll|StartRange|EndRange/ig))
229 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_missing, 'Data');
231 if (typeof callback == 'function') {
232 return context.callAsync(this, arguments.callee, criteria, callback);
235 var which = Data.IdList ? 'IdList' : 'LocalIdList',
236 idList = Data[which] || false;
239 // search for and delete items
240 for (var id in idList) {
242 for (var i in DBase[cal]) {
243 if (id == DBase[cal][i][which]) {
244 DBase[cal].splice(i, 1);
249 else if (Data.DeleteAll && Data.DeleteAll === true){
254 if (Data.StartRange || Data.EndRange) {
255 context.notify(_t('%s:: Delete : StartRange / EndRange not implemented in preview.').arg(provider));
259 return context.ErrorResult(device.implementation.ERR_SUCCESS);
265 * @param {Object} criteria
266 * @param {function} callback function for async call (optional)
268 function __Import(criteria, callback){
270 if ((result = validator.apply('Import', arguments)) !== false)
273 var Data = criteria.Data || false;
275 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Data');
278 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'FileName');
281 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Format');
283 if (typeof callback == 'function') {
284 return context.callAsync(this, arguments.callee, criteria, callback);
287 context.notify(_t('%s:: Import : not implemented in preview.').arg(provider));
288 var returnValue = context.Iterator([]);
289 return context.Result(returnValue, device.implementation.ERR_SUCCESS);
295 * @param {Object} criteria
296 * @param {function} callback function for async call (optional)
298 function __Export(criteria, callback){
300 if ((result = validator.apply('Export', arguments)) !== false)
303 var Data = criteria.Data || false;
305 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Data');
308 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Format');
310 if (typeof callback == 'function') {
311 return context.callAsync(this, arguments.callee, criteria, callback);
313 context.notify(_t('%s:: Export : not implemented in preview.').arg(provider));
314 var returnValue = '';
315 return context.Result(returnValue, device.implementation.ERR_SUCCESS);
320 * Calendar: RequestNotification
321 * @param {Object} criteria
322 * @param {function} callback function for async call
324 function __RequestNotification(criteria, callback){
326 if ((result = validator.apply('RequestNotification', arguments)) !== false)
329 if (typeof callback != 'function')
330 return error(device.implementation.ERR_SERVICE_NOT_SUPPORTED, msg.badAsync);
332 context.notify(_t('%s:: RequestNotification : not implemented in preview.').arg(provider));
333 var result = context.ErrorResult(device.implementation.ERR_SUCCESS);
334 result.TransactionID = 0;
341 * @param {Object} criteria
343 function __Cancel(criteria){
345 if (!criteria || !criteria.TransactionID)
346 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.missingTID);
348 clearTimeout(criteria.TransactionID);
349 return context.ErrorResult(device.implementation.ERR_SUCCESS);
354 /*******************************
356 *******************************/
358 function error(code, msg /*, args...*/){
360 var args = ['Calendar',method].concat([].slice.call(arguments,2));
361 msg = msg ? _t().arg.apply(msg,args) : undefined;
362 return context.ErrorResult(code, msg);
366 * validate common input arguments
367 * 'this' is string (object) name of calling function
369 * @param {arguments} arguments of calling function
370 * @return {Result} Result object if error, false if no error.
372 function validator() {
375 criteria = arguments[0] || false;
378 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
380 if (typeof criteria != 'object' || typeof criteria.Type == 'undefined')
381 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
383 var TypeRE = /Import|Export|RequestNotification/i.test(method)
385 : /^(Calendar|CalendarEntry)$/i;
387 if (!TypeRE.test(criteria.Type))
388 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
395 * order of %s args: Service name, method name, parameter name
398 badType : '%s : %s : Type is invalid',
399 badCalendar : '%s : %s : CalendarName is invalid',
400 missingCalendar : '%s : %s : CalendarName is missing',
401 missingTID : '%s : %s : TransactionID is missing',
402 badAsync : '%s : %s : Invalid async parameters',
403 noAsync : '%s : %s : Async not supported',
404 is_missing : '%s : %s : %s is missing',
405 is_invalid : '%s : %s : %s is invalid'