Changed zouba directory heirarchy.
[ptas] / zouba / misc / rss / preview / script / lib / sapi / Calendar.js
diff --git a/zouba/misc/rss/preview/script/lib/sapi/Calendar.js b/zouba/misc/rss/preview/script/lib/sapi/Calendar.js
new file mode 100644 (file)
index 0000000..e96f564
--- /dev/null
@@ -0,0 +1,410 @@
+/**
+ * Calendar.js
+ * 
+ * Nokia Web Runtime Service API emulation 
+ * WRT v1.1
+ * 
+ * Copyright 2009 Nokia Corporation. All rights reserved.
+*/
+
+(function(){
+       
+       var provider = 'Service.Calendar' ,
+               Interface = 'IDataSource';
+
+       /**
+        * Calendar service
+        */
+       var CalendarService = function(){
+               this.GetList    = __GetList;
+               this.Add                = __Add;
+               this.Delete     = __Delete;
+               this.Import     = __Import;
+               this.Export     = __Export;
+               this.Cancel     = __Cancel;
+               this.RequestNotification = __RequestNotification;
+       }
+
+       device.implementation.extend(provider, Interface, new CalendarService() );
+
+
+       /******************************************************/        
+       /******************************************************/        
+       /******************************************************/        
+
+       var     context = device.implementation.context,
+               _t = context._t,
+               method = '',
+               result = false,
+               DBase = null,
+               default_calendar = 'C:Calendar';
+       
+       /**
+        * Calendar: GetList
+        * @param {Object} criteria
+        */
+       function __GetList(criteria){
+               if ((result = validator.apply('GetList', arguments)) !== false)
+                       return result; 
+
+               var returnValue = [], 
+                       match = null,
+                       filter = criteria.Filter || null;
+               DBase = context.getData(provider);
+
+               // Type = Calendar
+               if (!/CalendarEntry/i.test(criteria.Type)){
+                       var cals = [default_calendar];
+                       if (filter && filter.DefaultCalendar === false)
+                               cals = context.keys(DBase)
+
+                       returnValue = cals;
+
+               } else {
+               // Type = CalendarEntry
+                       var cal = default_calendar;
+                       if (filter && filter.CalendarName)
+                               cal = filter.CalendarName;
+                       
+                       if (!(cal in DBase))
+                               return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badCalendar);
+
+                       // filter by id or LocalId
+                       if (filter && (filter.id || filter.LocalId)) {
+                               var which = filter.id ? 'id' : 'LocalId', 
+                                       id = filter[which];
+                                       
+                               for (var i in DBase[cal]) {
+                                       if (id == DBase[cal][i][which]) {
+                                               returnValue.push(DBase[cal][i]);
+                                       }
+                               }
+                       }
+                       // filter by type 
+                       else if (filter && filter.Type && !/IncludeAll/i.test(filter.Type)) {
+                               for (var i in DBase[cal]) {
+                                       // match on type is case insensitive
+                                       if (filter.Type.toLowerCase() == DBase[cal][i].Type.toLowerCase()) {
+                                               returnValue.push(DBase[cal][i]);
+                                       }
+                               }
+                       }
+                       // unsupported filters 
+                       else if (filter 
+                               && (match = context.keys(filter).join().match(/StartRange|EndRange|SearchText/ig)) ) {
+                               context.notify(_t('%s:: GetList : filter %s not implemented in preview').arg(provider, match.join()));
+                       }
+                       // return everything 
+                       else {
+                               returnValue = DBase[cal];
+                       }
+               }
+
+               return context.Result(context.Iterator(returnValue));
+       }
+                       
+       /**
+        * Calendar: Add
+        * @param {Object} criteria
+        */
+       function __Add(criteria){
+               if ((result = validator.apply('Add', arguments)) !== false)
+                       return result; 
+               
+               var Item = criteria.Item || false; 
+               
+               DBase = context.getData(provider);
+
+               // Type = Calendar
+               if (!/CalendarEntry/i.test(criteria.Type)){
+
+                       if (!Item || !Item.CalendarName)
+                               return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.missingCalendar);
+                               
+                       var cal = Item.CalendarName;
+                       if (cal in DBase) {
+                               return error(device.implementation.ERR_ENTRY_EXISTS);
+                       }
+
+                       // @todo: validate calendar name <drive>:<name>
+                       // return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badCalendar);
+                       
+                       // create new calendar
+                       device.implementation.loadData(provider, cal, []);
+                       return error(device.implementation.ERR_SUCCESS);
+
+               } else {
+               // Type = CalendarEntry
+
+                       if (!Item)
+                               return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_missing, 'Item');
+                               
+                       var cal = Item.CalendarName || default_calendar;
+
+                       // if calendar doesn't exist and it's the default, create it
+                       if (!(cal in DBase) && cal == default_calendar)
+                               device.implementation.loadData(provider, cal, []);
+                       
+                       if (!(cal in DBase))
+                               return error(device.implementation.ERR_NOT_FOUND);
+
+                       // update existing item?
+                       if ('LocalId' in Item) {
+                               
+                               if (!Item.LocalId && Item.LocalId !== 0)
+                                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'LocalId');
+                               
+                               if ('InstanceStartTime' in Item)
+                                       context.notify(_t('%s:: Add : InstanceStartTime not implemented in preview.').arg(provider));
+
+                               // can't update id
+                               delete Item.id;
+                               
+                               //  search for and update item
+                               var found = false;
+                               for (var i in DBase[cal]) {
+                                       var entry = DBase[cal][i];
+                                       if (entry.LocalId == Item.LocalId) {
+                                               context.extend(entry, Item);
+                                               Item.id = entry.id;
+                                               found = true;
+                                               break;
+                                       }
+                               }
+                               if (!found)
+                                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'LocalId');
+
+                       } else {
+                       // add new item
+                               // generate new id and localId 
+                               // -- in calendar id's are string!
+                               Item.id = String(context.getUniqueID());
+                               Item.LocalId = String(context.getUniqueID());
+                               DBase[cal].push(Item);
+                       } 
+               } 
+               // return success
+               return context.Result(Item.id, device.implementation.ERR_SUCCESS);
+       }
+                       
+
+       /**
+        * Calendar: Delete
+        * @param {Object} criteria
+        * @param {function} callback function for async call (optional - valid only for CalendarEntry)
+        */
+       function __Delete(criteria, callback){
+               
+               if ((result = validator.apply('Delete', arguments)) !== false)
+                       return result; 
+
+               var Data = criteria.Data || false; 
+               if (!Data || typeof Data != 'object')
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Data');
+               
+               // only sync call supported for Calendar
+               if (!/CalendarEntry/i.test(criteria.Type) && typeof callback == 'function')
+                       return error(device.implementation.ERR_SERVICE_NOT_SUPPORTED, msg.noAsync);
+
+               DBase = context.getData(provider);
+               var cal = Data.CalendarName || default_calendar;                        
+               if (!(cal in DBase))
+                       return error(device.implementation.ERR_NOT_FOUND);
+               
+               // Type = Calendar
+               if (!/CalendarEntry/i.test(criteria.Type)) {
+                       // CalendarName is mandatory
+                       if (!Data.CalendarName)
+                               return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_missing, 'CalendarName');
+                                               
+                       DBase[cal] = null;
+                       delete DBase[cal];
+               }
+               else {
+               // Type = CalendarEntry
+
+                       if (!context.keys(Data).join().match(/IdList|LocalIdList|DeleteAll|StartRange|EndRange/ig))
+                               return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_missing, 'Data');
+
+                       if (typeof callback == 'function') {
+                               return context.callAsync(this, arguments.callee, criteria, callback);
+                       }
+
+                       var which = Data.IdList ? 'IdList' : 'LocalIdList',
+                               idList = Data[which] || false;
+                               
+                       if (idList) {
+                               //  search for and delete items
+                               for (var id in idList) {
+                                       id = idList[id];
+                                       for (var i in DBase[cal]) {
+                                               if (id == DBase[cal][i][which]) {
+                                                       DBase[cal].splice(i, 1);
+                                               }
+                                       }
+                               }
+                       }
+                       else if (Data.DeleteAll && Data.DeleteAll === true){
+                               delete DBase[cal];
+                               DBase[cal] = [];
+                       }
+
+                       if (Data.StartRange || Data.EndRange) {
+                               context.notify(_t('%s:: Delete : StartRange / EndRange not implemented in preview.').arg(provider));
+                       }
+               }
+               // return success
+               return context.ErrorResult(device.implementation.ERR_SUCCESS);                          
+       }
+                       
+
+       /**
+        * Calendar: Import
+        * @param {Object} criteria
+        * @param {function} callback function for async call (optional)
+        */
+       function __Import(criteria, callback){
+
+               if ((result = validator.apply('Import', arguments)) !== false)
+                       return result; 
+
+               var Data = criteria.Data || false; 
+               if (!Data)
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Data');
+               
+               if (!Data.FileName)
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'FileName');
+
+               if (!Data.Format)
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Format');
+
+               if (typeof callback == 'function') {
+                       return context.callAsync(this, arguments.callee, criteria, callback);
+               }
+
+               context.notify(_t('%s:: Import : not implemented in preview.').arg(provider));
+               var returnValue = context.Iterator([]);
+               return context.Result(returnValue, device.implementation.ERR_SUCCESS);          
+       }
+                       
+
+       /**
+        * Calendar: Export
+        * @param {Object} criteria
+        * @param {function} callback function for async call (optional)
+        */
+       function __Export(criteria, callback){
+
+               if ((result = validator.apply('Export', arguments)) !== false)
+                       return result; 
+
+               var Data = criteria.Data || false; 
+               if (!Data)
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Data');
+
+               if (!Data.Format)
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.is_invalid, 'Format');
+
+               if (typeof callback == 'function') {
+                       return context.callAsync(this, arguments.callee, criteria, callback);
+               }
+               context.notify(_t('%s:: Export : not implemented in preview.').arg(provider));
+               var returnValue = '';
+               return context.Result(returnValue, device.implementation.ERR_SUCCESS);          
+       }
+                       
+
+       /**
+        * Calendar: RequestNotification
+        * @param {Object} criteria
+        * @param {function} callback function for async call 
+        */
+       function __RequestNotification(criteria, callback){
+
+               if ((result = validator.apply('RequestNotification', arguments)) !== false)
+                       return result; 
+
+               if (typeof callback != 'function')
+                       return error(device.implementation.ERR_SERVICE_NOT_SUPPORTED, msg.badAsync);
+
+               context.notify(_t('%s:: RequestNotification : not implemented in preview.').arg(provider));
+               var result = context.ErrorResult(device.implementation.ERR_SUCCESS);
+               result.TransactionID = 0;
+               return result;          
+       }
+                       
+
+       /**
+        * Calendar: Cancel
+        * @param {Object} criteria
+        */
+       function __Cancel(criteria){
+               method = 'Cancel';
+               if (!criteria || !criteria.TransactionID)
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.missingTID);
+               
+               clearTimeout(criteria.TransactionID);
+               return context.ErrorResult(device.implementation.ERR_SUCCESS);
+       }
+
+
+       
+       /*******************************
+        * helper functions
+        *******************************/
+       
+       function error(code, msg /*, args...*/){
+
+               var args = ['Calendar',method].concat([].slice.call(arguments,2));
+               msg = msg ? _t().arg.apply(msg,args) : undefined;
+               return context.ErrorResult(code, msg);
+       }
+
+       /**
+        * validate common input arguments
+        * 'this' is string (object) name of calling function
+        * 
+        * @param {arguments} arguments of calling function
+        * @return {Result} Result object if error, false if no error.
+        */
+       function validator() {
+               method = ''+this;
+               var     failed = false,
+                       criteria = arguments[0] || false;
+                       
+               if (!criteria)
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
+                       
+               if (typeof criteria != 'object' || typeof criteria.Type == 'undefined')
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
+               
+               var TypeRE = /Import|Export|RequestNotification/i.test(method)
+                       ? /^CalendarEntry$/i
+                       : /^(Calendar|CalendarEntry)$/i;
+                
+               if (!TypeRE.test(criteria.Type)) 
+                       return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
+               
+               return failed;
+       }
+
+       /** 
+        * error messages
+        * order of %s args: Service name, method name, parameter name 
+        */
+       var msg = {
+               badType                 : '%s : %s : Type is invalid',
+               badCalendar             : '%s : %s : CalendarName is invalid',
+               missingCalendar : '%s : %s : CalendarName is missing',
+               missingTID              : '%s : %s : TransactionID is missing',
+               badAsync                : '%s : %s : Invalid async parameters',
+               noAsync                 : '%s : %s : Async not supported',
+               is_missing              : '%s : %s : %s is missing',
+               is_invalid              : '%s : %s : %s is invalid'
+       };
+               
+
+}) ();
+