Wikipedia/preview/script/lib/sapi/Messaging.js
changeset 20 918767a9c8d3
equal deleted inserted replaced
19:f3521a11d878 20:918767a9c8d3
       
     1 /**
       
     2  * Messaging.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 (function(){
       
    11 	
       
    12 	var provider = 'Service.Messaging' ,
       
    13 		Interface = 'IMessaging';
       
    14 		
       
    15 	/**
       
    16 	 * Messaging service
       
    17 	 */
       
    18 	var MessagingService = function(){
       
    19 		this.GetList			 	= __GetList;
       
    20 		this.Send 					= __Send;
       
    21 		this.RegisterNotification	= __RegisterNotification;
       
    22 		this.CancelNotification 	= __CancelNotification;
       
    23 		this.ChangeStatus 			= __ChangeStatus;
       
    24 		this.Delete					= __Delete;
       
    25 		this.Cancel 				= __Cancel;
       
    26 	}
       
    27 
       
    28 	device.implementation.extend(provider, Interface, new MessagingService() );
       
    29 
       
    30 
       
    31 	/******************************************************/	
       
    32 	/******************************************************/	
       
    33 	/******************************************************/	
       
    34 
       
    35 	var	context = device.implementation.context,
       
    36 		_t = context._t,
       
    37 		method = '',
       
    38 		result = false,
       
    39 		DBase = null;
       
    40 	
       
    41 	/**
       
    42 	 * Messaging: GetList
       
    43 	 * @param {Object} criteria
       
    44 	 */
       
    45 	function __GetList(criteria){
       
    46 
       
    47 		if ((result = validator.apply('GetList', arguments)) !== false)
       
    48 			return result; 
       
    49 	
       
    50 		if (!criteria.Type)
       
    51 			return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType);
       
    52 
       
    53 		if (!/^Inbox$/i.test(criteria.Type))
       
    54 			return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
       
    55 	
       
    56 		var returnValue = [], 
       
    57 			match = null,
       
    58 			filter = criteria.Filter || null;
       
    59  
       
    60 		DBase = context.getData(provider);
       
    61 
       
    62 		// filter by MessageId
       
    63 		if (filter && filter.MessageId) {
       
    64 			returnValue = findByKey(DBase.Inbox, filter.MessageId, 'MessageId'); 
       
    65 			if (returnValue.length == 0)
       
    66 				return error(device.implementation.ERR_NOT_FOUND);
       
    67 		}
       
    68 		// return all messages
       
    69 		else {
       
    70 			returnValue = DBase.Inbox;
       
    71 		}
       
    72 
       
    73 		// unsupported filters 
       
    74 		if (filter 
       
    75 			&& (match = context.keys(filter).join().match(/MessageTypeList|SenderList|Subject|StartDate|EndDate/ig)) ) {
       
    76 			context.notify(_t('%s:: GetList : filter %s not implemented in preview').arg(provider, match.join()));
       
    77 		}
       
    78 		// unsupported sort			
       
    79 		if (criteria.Sort) { 
       
    80 			context.notify(_t('%s:: GetList : sort not implemented in preview').arg(provider));
       
    81 		}
       
    82 		return context.Result(context.Iterator(returnValue));
       
    83 	}
       
    84 			
       
    85 	/**
       
    86 	 * Messaging: Send
       
    87 	 * @param {Object} criteria
       
    88 	 * @param {Function} [callback] function for async call (optional)
       
    89 	 */
       
    90 	function __Send(criteria, callback){
       
    91 
       
    92 		if ((result = validator.apply('Send', arguments)) !== false)
       
    93 			return result; 
       
    94 
       
    95 		if (!criteria.MessageType)
       
    96 			return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.missingMessageType);
       
    97 			
       
    98 		if (!/^(SMS|MMS)$/i.test(criteria.MessageType))
       
    99 			return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badMessageType);
       
   100 
       
   101 		if (!criteria.To)
       
   102 			return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingTo);
       
   103 		
       
   104 		// async call?
       
   105 		if (typeof callback == 'function') {
       
   106 			return context.callAsync(this, arguments.callee, criteria, callback);
       
   107 		}
       
   108 
       
   109 		context.notify(_t('%s:: Send : message sent!').arg(provider));
       
   110 
       
   111 		// return success
       
   112 		return error(device.implementation.ERR_SUCCESS);
       
   113 	}
       
   114 			
       
   115 
       
   116 	/**
       
   117 	 * Messaging: RegisterNotification
       
   118 	 * @param {Object} criteria
       
   119 	 * @param {function} callback function for async call (mandatory)
       
   120 	 */
       
   121 	function __RegisterNotification(criteria, callback){
       
   122 
       
   123 		if ((result = validator.apply('RegisterNotification', arguments)) !== false)
       
   124 			return result; 
       
   125 
       
   126 		// callback is mandatory
       
   127 		if (typeof callback != 'function')
       
   128 			return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badAsync);
       
   129 		
       
   130 		// continue validation after callback check		
       
   131 		if (typeof criteria.Type == 'undefined') 
       
   132 			return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType);
       
   133 		
       
   134 		if (!/^NewMessage$/i.test(criteria.Type)) 
       
   135 			return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
       
   136 
       
   137 		var eventType =  'NewMessage';
       
   138 
       
   139 		// check for multiple registration
       
   140 		if (context.hasListener(provider, eventType))
       
   141 			return error(device.implementation.ERR_ENTRY_EXISTS);
       
   142 				
       
   143 		// process notify
       
   144 		return context.addListener(provider, eventType, criteria, callback, notifyHandler);
       
   145 	}
       
   146 			
       
   147 	function notifyHandler(transactionID, criteria, callback, data){
       
   148 		
       
   149 		var result,
       
   150 			eventCode = {completed:2, error:4, progress:9},
       
   151 			code = eventCode.progress;
       
   152 		try{
       
   153 			DBase = context.getData(provider);
       
   154 			
       
   155 			// make new message
       
   156 			var now = new Date();
       
   157 			var message = {
       
   158 			 	"MessageType": "SMS",
       
   159 				"Sender": "0435445454",
       
   160 				"Subject": "new message",
       
   161 				"Time": _t("%s, %s").arg(now.toString().substr(0,3), now.toLocaleString()),
       
   162 				"Priority": "Medium",
       
   163 				"Attachment": false,
       
   164 				"Unread": true,
       
   165 				"MessageId": context.getUniqueID(),
       
   166 				"BodyText": "My hovercraft is full of eels!"
       
   167 			};
       
   168 			
       
   169 			// extend with optional data
       
   170 			data = typeof data=='object' && !(data instanceof Array) ? data : {};
       
   171 			var returnValue = context.extend(message, data);
       
   172 
       
   173 			result = context.Result(returnValue);
       
   174 			
       
   175 			/// add to top of inbox
       
   176 			DBase.Inbox.unshift(message);
       
   177 		} 
       
   178 		catch(e){
       
   179 			code = eventCode.error;
       
   180 		}
       
   181 		callback(transactionID, code, result);
       
   182 	}
       
   183 	
       
   184 	/**
       
   185 	 * Messaging: CancelNotification
       
   186 	 * @param {Object} criteria
       
   187 	 */
       
   188 	function __CancelNotification(criteria){
       
   189 
       
   190 		if ((result = validator.apply('CancelNotification', arguments)) !== false)
       
   191 			return result; 
       
   192 
       
   193 		if (typeof criteria.Type == 'undefined') 
       
   194 			return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType);
       
   195 
       
   196 		if (!/^NewMessage$/i.test(criteria.Type)) 
       
   197 			return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
       
   198 
       
   199 		var eventType = 'NewMessage';
       
   200 		context.removeListener(provider, eventType);
       
   201 		return context.ErrorResult(device.implementation.ERR_SUCCESS);
       
   202 	}
       
   203 			
       
   204 			
       
   205 	/**
       
   206 	 * Messaging: ChangeStatus
       
   207 	 * @param {Object} criteria
       
   208 	 */
       
   209 	function __ChangeStatus(criteria){
       
   210 
       
   211 		if ((result = validator.apply('ChangeStatus', arguments)) !== false)
       
   212 			return result; 
       
   213 
       
   214 		if (!criteria.MessageId)
       
   215 			return error(device.implementation.ERR_MISSING_ARGUMENT, msg.is_missing ,'MessageId');
       
   216 			
       
   217 		if (typeof criteria.MessageId != 'number')
       
   218 			return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badMessageIdType);
       
   219 			
       
   220 		if (!criteria.Status)
       
   221 			return error(device.implementation.ERR_MISSING_ARGUMENT, msg.is_missing ,'Status');
       
   222 
       
   223 		if (!/^(Read|Unread|Replied|Forwarded)$/i.test(criteria.Status))
       
   224 			return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badStatus);
       
   225 	
       
   226 		// check if a callback was provided
       
   227 		if (arguments.length > 1)
       
   228 			return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badAsync2);
       
   229 			
       
   230 		DBase = context.getData(provider);
       
   231 
       
   232 		var i,item, found = false;
       
   233 		for (i in DBase.Inbox) {
       
   234 			item = DBase.Inbox[i];
       
   235 			if (criteria.MessageId == item.MessageId) {
       
   236 				item.Unread = /Unread/i.test(criteria.Status);
       
   237 				found = true;
       
   238 			}
       
   239 		}
       
   240 		if (!found)
       
   241 			return error(device.implementation.ERR_NOT_FOUND);
       
   242 
       
   243 		// return success
       
   244 		return error(device.implementation.ERR_SUCCESS);				
       
   245 	}
       
   246 						
       
   247 	/**
       
   248 	 * Messaging: Delete
       
   249 	 * @param {Object} criteria
       
   250 	 */
       
   251 	function __Delete(criteria){
       
   252 		
       
   253 		if ((result = validator.apply('Delete', arguments)) !== false)
       
   254 			return result; 
       
   255 
       
   256 		if (typeof criteria.MessageId == 'undefined')
       
   257 			return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingMessageId);
       
   258 
       
   259 		if (typeof criteria.MessageId != 'number')
       
   260 			return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badMessageIdType);
       
   261 					
       
   262 		if (criteria.MessageId < 0)
       
   263 			return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badMessageId);
       
   264 			
       
   265 		DBase = context.getData(provider);
       
   266 
       
   267 		var i,item, found = false;
       
   268 		for (i in DBase.Inbox) {
       
   269 			item = DBase.Inbox[i];
       
   270 			if (criteria.MessageId == item.MessageId) {
       
   271 				DBase.Inbox.splice(i, 1);
       
   272 				found = true;
       
   273 			}
       
   274 		}
       
   275 		if (!found)
       
   276 			return error(device.implementation.ERR_NOT_FOUND);
       
   277 			
       
   278 		// return success
       
   279 		return error(device.implementation.ERR_SUCCESS);				
       
   280 	}
       
   281 			
       
   282 
       
   283 	/**
       
   284 	 * Messaging: Cancel
       
   285 	 * @param {Object} criteria
       
   286 	 */
       
   287 	function __Cancel(criteria){
       
   288 		method = 'Cancel';
       
   289 		if (!criteria || !criteria.TransactionID)
       
   290 			return error(device.implementation.ERR_MISSING_ARGUMENT, msg.is_missing, 'TransactionID');
       
   291 		
       
   292 		clearTimeout(criteria.TransactionID);
       
   293 		return context.ErrorResult(device.implementation.ERR_SUCCESS);
       
   294 	}
       
   295 
       
   296 	
       
   297 	/*******************************
       
   298 	 * helper functions
       
   299 	 *******************************/
       
   300 	
       
   301 	function error(code, msg /*, args...*/){
       
   302 
       
   303 		var args = ['Messaging',method].concat([].slice.call(arguments,2));
       
   304 		msg = msg ? _t().arg.apply(msg,args) : undefined;
       
   305 		return context.ErrorResult(code, msg);
       
   306 	}
       
   307 
       
   308 	/**
       
   309 	 * validate common input arguments
       
   310 	 * 'this' is string (object) name of calling function
       
   311 	 * 
       
   312 	 * @param {arguments} arguments of calling function
       
   313 	 * @return {Result} Result object if error, false if no error.
       
   314 	 */
       
   315 	function validator() {
       
   316 		method = ''+this;
       
   317 		var	failed = false,
       
   318 			criteria = arguments[0] || false;
       
   319 
       
   320 		if (!criteria || typeof criteria != 'object')
       
   321 			return error(device.implementation.ERR_MISSING_ARGUMENT, 
       
   322 				method == 'Send' 
       
   323 				? msg.missingMessageType 
       
   324 				: (/ChangeStatus|Delete/.test(method) 
       
   325 					? msg.missingMessageId 
       
   326 					: msg.missingType) );
       
   327 			
       
   328 		return failed;
       
   329 	}
       
   330 
       
   331 
       
   332 	function findByKey(dbase, value, key){
       
   333 		var result = [];
       
   334 		for (var i in dbase) {
       
   335 			if (value == dbase[i][key]) {
       
   336 				result.push(dbase[i]);
       
   337 			}
       
   338 		}
       
   339 		return result;
       
   340 	}
       
   341 
       
   342 	/** 
       
   343 	 * error messages
       
   344 	 * order of %s args: Service name, method name, parameter name 
       
   345 	 */
       
   346 	var msg = {
       
   347 		missingType		: '%s:%s:Type Missing',
       
   348 		badType			: '%s:%s:Type Value Incorrect',
       
   349 		missingTo		: '%s:%s:To Missing',
       
   350 		badTo			: '%s:%s:To Value Incorrect',
       
   351 		missingMessageType	: '%s:%s:MessageType Missing',
       
   352 		badMessageType	: '%s:%s:MessageType Value Incorrect',
       
   353 		badAsync		: '%s:%s:Synchronous Operation not supported',
       
   354 		badAsync2		: '%s:%s:Asynchronous Operation not supported',
       
   355 		missingMessageId	: '%s:%s:MessageId Missing',
       
   356 		badMessageIdType: '%s:%s:MessageId Type Invalid',
       
   357 		badMessageId	: '%s:%s:MessageId Value Incorrect',
       
   358 		badStatus		: '%s:%s:Status Value Incorrect',
       
   359 
       
   360 		is_missing		: '%s:%s:%s Missing',
       
   361 		is_invalid		: '%s:%s:%s Value Incorrect'
       
   362 	};
       
   363 		
       
   364 
       
   365 }) ()
       
   366