4 * Nokia Web Runtime Service API emulation
7 * Copyright 2009 Nokia Corporation. All rights reserved.
12 var provider = 'Service.Messaging' ,
13 Interface = 'IMessaging';
18 var MessagingService = function(){
19 this.GetList = __GetList;
21 this.RegisterNotification = __RegisterNotification;
22 this.CancelNotification = __CancelNotification;
23 this.ChangeStatus = __ChangeStatus;
24 this.Delete = __Delete;
25 this.Cancel = __Cancel;
28 device.implementation.extend(provider, Interface, new MessagingService() );
31 /******************************************************/
32 /******************************************************/
33 /******************************************************/
35 var context = device.implementation.context,
43 * @param {Object} criteria
45 function __GetList(criteria){
47 if ((result = validator.apply('GetList', arguments)) !== false)
51 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType);
53 if (!/^Inbox$/i.test(criteria.Type))
54 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
58 filter = criteria.Filter || null;
60 DBase = context.getData(provider);
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);
68 // return all messages
70 returnValue = DBase.Inbox;
73 // unsupported filters
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()));
80 context.notify(_t('%s:: GetList : sort not implemented in preview').arg(provider));
82 return context.Result(context.Iterator(returnValue));
87 * @param {Object} criteria
88 * @param {Function} [callback] function for async call (optional)
90 function __Send(criteria, callback){
92 if ((result = validator.apply('Send', arguments)) !== false)
95 if (!criteria.MessageType)
96 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.missingMessageType);
98 if (!/^(SMS|MMS)$/i.test(criteria.MessageType))
99 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badMessageType);
102 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingTo);
105 if (typeof callback == 'function') {
106 return context.callAsync(this, arguments.callee, criteria, callback);
109 context.notify(_t('%s:: Send : message sent!').arg(provider));
112 return error(device.implementation.ERR_SUCCESS);
117 * Messaging: RegisterNotification
118 * @param {Object} criteria
119 * @param {function} callback function for async call (mandatory)
121 function __RegisterNotification(criteria, callback){
123 if ((result = validator.apply('RegisterNotification', arguments)) !== false)
126 // callback is mandatory
127 if (typeof callback != 'function')
128 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badAsync);
130 // continue validation after callback check
131 if (typeof criteria.Type == 'undefined')
132 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType);
134 if (!/^NewMessage$/i.test(criteria.Type))
135 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
137 var eventType = 'NewMessage';
139 // check for multiple registration
140 if (context.hasListener(provider, eventType))
141 return error(device.implementation.ERR_ENTRY_EXISTS);
144 return context.addListener(provider, eventType, criteria, callback, notifyHandler);
147 function notifyHandler(transactionID, criteria, callback, data){
150 eventCode = {completed:2, error:4, progress:9},
151 code = eventCode.progress;
153 DBase = context.getData(provider);
156 var now = new Date();
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",
165 "MessageId": context.getUniqueID(),
166 "BodyText": "My hovercraft is full of eels!"
169 // extend with optional data
170 data = typeof data=='object' && !(data instanceof Array) ? data : {};
171 var returnValue = context.extend(message, data);
173 result = context.Result(returnValue);
175 /// add to top of inbox
176 DBase.Inbox.unshift(message);
179 code = eventCode.error;
181 callback(transactionID, code, result);
185 * Messaging: CancelNotification
186 * @param {Object} criteria
188 function __CancelNotification(criteria){
190 if ((result = validator.apply('CancelNotification', arguments)) !== false)
193 if (typeof criteria.Type == 'undefined')
194 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType);
196 if (!/^NewMessage$/i.test(criteria.Type))
197 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
199 var eventType = 'NewMessage';
200 context.removeListener(provider, eventType);
201 return context.ErrorResult(device.implementation.ERR_SUCCESS);
206 * Messaging: ChangeStatus
207 * @param {Object} criteria
209 function __ChangeStatus(criteria){
211 if ((result = validator.apply('ChangeStatus', arguments)) !== false)
214 if (!criteria.MessageId)
215 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.is_missing ,'MessageId');
217 if (typeof criteria.MessageId != 'number')
218 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badMessageIdType);
220 if (!criteria.Status)
221 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.is_missing ,'Status');
223 if (!/^(Read|Unread|Replied|Forwarded)$/i.test(criteria.Status))
224 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badStatus);
226 // check if a callback was provided
227 if (arguments.length > 1)
228 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badAsync2);
230 DBase = context.getData(provider);
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);
241 return error(device.implementation.ERR_NOT_FOUND);
244 return error(device.implementation.ERR_SUCCESS);
249 * @param {Object} criteria
251 function __Delete(criteria){
253 if ((result = validator.apply('Delete', arguments)) !== false)
256 if (typeof criteria.MessageId == 'undefined')
257 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingMessageId);
259 if (typeof criteria.MessageId != 'number')
260 return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badMessageIdType);
262 if (criteria.MessageId < 0)
263 return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badMessageId);
265 DBase = context.getData(provider);
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);
276 return error(device.implementation.ERR_NOT_FOUND);
279 return error(device.implementation.ERR_SUCCESS);
285 * @param {Object} criteria
287 function __Cancel(criteria){
289 if (!criteria || !criteria.TransactionID)
290 return error(device.implementation.ERR_MISSING_ARGUMENT, msg.is_missing, 'TransactionID');
292 clearTimeout(criteria.TransactionID);
293 return context.ErrorResult(device.implementation.ERR_SUCCESS);
297 /*******************************
299 *******************************/
301 function error(code, msg /*, args...*/){
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);
309 * validate common input arguments
310 * 'this' is string (object) name of calling function
312 * @param {arguments} arguments of calling function
313 * @return {Result} Result object if error, false if no error.
315 function validator() {
318 criteria = arguments[0] || false;
320 if (!criteria || typeof criteria != 'object')
321 return error(device.implementation.ERR_MISSING_ARGUMENT,
323 ? msg.missingMessageType
324 : (/ChangeStatus|Delete/.test(method)
325 ? msg.missingMessageId
326 : msg.missingType) );
332 function findByKey(dbase, value, key){
334 for (var i in dbase) {
335 if (value == dbase[i][key]) {
336 result.push(dbase[i]);
344 * order of %s args: Service name, method name, parameter name
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',
360 is_missing : '%s:%s:%s Missing',
361 is_invalid : '%s:%s:%s Value Incorrect'