/**
* Messaging.js
*
* Nokia Web Runtime Service API emulation
* WRT v1.1
*
* Copyright 2009 Nokia Corporation. All rights reserved.
*/
(function(){
var provider = 'Service.Messaging' ,
Interface = 'IMessaging';
/**
* Messaging service
*/
var MessagingService = function(){
this.GetList = __GetList;
this.Send = __Send;
this.RegisterNotification = __RegisterNotification;
this.CancelNotification = __CancelNotification;
this.ChangeStatus = __ChangeStatus;
this.Delete = __Delete;
this.Cancel = __Cancel;
}
device.implementation.extend(provider, Interface, new MessagingService() );
/******************************************************/
/******************************************************/
/******************************************************/
var context = device.implementation.context,
_t = context._t,
method = '',
result = false,
DBase = null;
/**
* Messaging: GetList
* @param {Object} criteria
*/
function __GetList(criteria){
if ((result = validator.apply('GetList', arguments)) !== false)
return result;
if (!criteria.Type)
return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType);
if (!/^Inbox$/i.test(criteria.Type))
return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
var returnValue = [],
match = null,
filter = criteria.Filter || null;
DBase = context.getData(provider);
// filter by MessageId
if (filter && filter.MessageId) {
returnValue = findByKey(DBase.Inbox, filter.MessageId, 'MessageId');
if (returnValue.length == 0)
return error(device.implementation.ERR_NOT_FOUND);
}
// return all messages
else {
returnValue = DBase.Inbox;
}
// unsupported filters
if (filter
&& (match = context.keys(filter).join().match(/MessageTypeList|SenderList|Subject|StartDate|EndDate/ig)) ) {
context.notify(_t('%s:: GetList : filter %s not implemented in preview').arg(provider, match.join()));
}
// unsupported sort
if (criteria.Sort) {
context.notify(_t('%s:: GetList : sort not implemented in preview').arg(provider));
}
return context.Result(context.Iterator(returnValue));
}
/**
* Messaging: Send
* @param {Object} criteria
* @param {Function} [callback] function for async call (optional)
*/
function __Send(criteria, callback){
if ((result = validator.apply('Send', arguments)) !== false)
return result;
if (!criteria.MessageType)
return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.missingMessageType);
if (!/^(SMS|MMS)$/i.test(criteria.MessageType))
return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badMessageType);
if (!criteria.To)
return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingTo);
// async call?
if (typeof callback == 'function') {
return context.callAsync(this, arguments.callee, criteria, callback);
}
context.notify(_t('%s:: Send : message sent!').arg(provider));
// return success
return error(device.implementation.ERR_SUCCESS);
}
/**
* Messaging: RegisterNotification
* @param {Object} criteria
* @param {function} callback function for async call (mandatory)
*/
function __RegisterNotification(criteria, callback){
if ((result = validator.apply('RegisterNotification', arguments)) !== false)
return result;
// callback is mandatory
if (typeof callback != 'function')
return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badAsync);
// continue validation after callback check
if (typeof criteria.Type == 'undefined')
return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType);
if (!/^NewMessage$/i.test(criteria.Type))
return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
var eventType = 'NewMessage';
// check for multiple registration
if (context.hasListener(provider, eventType))
return error(device.implementation.ERR_ENTRY_EXISTS);
// process notify
return context.addListener(provider, eventType, criteria, callback, notifyHandler);
}
function notifyHandler(transactionID, criteria, callback, data){
var result,
eventCode = {completed:2, error:4, progress:9},
code = eventCode.progress;
try{
DBase = context.getData(provider);
// make new message
var now = new Date();
var message = {
"MessageType": "SMS",
"Sender": "0435445454",
"Subject": "new message",
"Time": _t("%s, %s").arg(now.toString().substr(0,3), now.toLocaleString()),
"Priority": "Medium",
"Attachment": false,
"Unread": true,
"MessageId": context.getUniqueID(),
"BodyText": "My hovercraft is full of eels!"
};
// extend with optional data
data = typeof data=='object' && !(data instanceof Array) ? data : {};
var returnValue = context.extend(message, data);
result = context.Result(returnValue);
/// add to top of inbox
DBase.Inbox.unshift(message);
}
catch(e){
code = eventCode.error;
}
callback(transactionID, code, result);
}
/**
* Messaging: CancelNotification
* @param {Object} criteria
*/
function __CancelNotification(criteria){
if ((result = validator.apply('CancelNotification', arguments)) !== false)
return result;
if (typeof criteria.Type == 'undefined')
return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingType);
if (!/^NewMessage$/i.test(criteria.Type))
return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badType);
var eventType = 'NewMessage';
context.removeListener(provider, eventType);
return context.ErrorResult(device.implementation.ERR_SUCCESS);
}
/**
* Messaging: ChangeStatus
* @param {Object} criteria
*/
function __ChangeStatus(criteria){
if ((result = validator.apply('ChangeStatus', arguments)) !== false)
return result;
if (!criteria.MessageId)
return error(device.implementation.ERR_MISSING_ARGUMENT, msg.is_missing ,'MessageId');
if (typeof criteria.MessageId != 'number')
return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badMessageIdType);
if (!criteria.Status)
return error(device.implementation.ERR_MISSING_ARGUMENT, msg.is_missing ,'Status');
if (!/^(Read|Unread|Replied|Forwarded)$/i.test(criteria.Status))
return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badStatus);
// check if a callback was provided
if (arguments.length > 1)
return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badAsync2);
DBase = context.getData(provider);
var i,item, found = false;
for (i in DBase.Inbox) {
item = DBase.Inbox[i];
if (criteria.MessageId == item.MessageId) {
item.Unread = /Unread/i.test(criteria.Status);
found = true;
}
}
if (!found)
return error(device.implementation.ERR_NOT_FOUND);
// return success
return error(device.implementation.ERR_SUCCESS);
}
/**
* Messaging: Delete
* @param {Object} criteria
*/
function __Delete(criteria){
if ((result = validator.apply('Delete', arguments)) !== false)
return result;
if (typeof criteria.MessageId == 'undefined')
return error(device.implementation.ERR_MISSING_ARGUMENT, msg.missingMessageId);
if (typeof criteria.MessageId != 'number')
return error(device.implementation.ERR_BAD_ARGUMENT_TYPE, msg.badMessageIdType);
if (criteria.MessageId < 0)
return error(device.implementation.ERR_INVALID_SERVICE_ARGUMENT, msg.badMessageId);
DBase = context.getData(provider);
var i,item, found = false;
for (i in DBase.Inbox) {
item = DBase.Inbox[i];
if (criteria.MessageId == item.MessageId) {
DBase.Inbox.splice(i, 1);
found = true;
}
}
if (!found)
return error(device.implementation.ERR_NOT_FOUND);
// return success
return error(device.implementation.ERR_SUCCESS);
}
/**
* Messaging: Cancel
* @param {Object} criteria
*/
function __Cancel(criteria){
method = 'Cancel';
if (!criteria || !criteria.TransactionID)
return error(device.implementation.ERR_MISSING_ARGUMENT, msg.is_missing, 'TransactionID');
clearTimeout(criteria.TransactionID);
return context.ErrorResult(device.implementation.ERR_SUCCESS);
}
/*******************************
* helper functions
*******************************/
function error(code, msg /*, args...*/){
var args = ['Messaging',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 || typeof criteria != 'object')
return error(device.implementation.ERR_MISSING_ARGUMENT,
method == 'Send'
? msg.missingMessageType
: (/ChangeStatus|Delete/.test(method)
? msg.missingMessageId
: msg.missingType) );
return failed;
}
function findByKey(dbase, value, key){
var result = [];
for (var i in dbase) {
if (value == dbase[i][key]) {
result.push(dbase[i]);
}
}
return result;
}
/**
* error messages
* order of %s args: Service name, method name, parameter name
*/
var msg = {
missingType : '%s:%s:Type Missing',
badType : '%s:%s:Type Value Incorrect',
missingTo : '%s:%s:To Missing',
badTo : '%s:%s:To Value Incorrect',
missingMessageType : '%s:%s:MessageType Missing',
badMessageType : '%s:%s:MessageType Value Incorrect',
badAsync : '%s:%s:Synchronous Operation not supported',
badAsync2 : '%s:%s:Asynchronous Operation not supported',
missingMessageId : '%s:%s:MessageId Missing',
badMessageIdType: '%s:%s:MessageId Type Invalid',
badMessageId : '%s:%s:MessageId Value Incorrect',
badStatus : '%s:%s:Status Value Incorrect',
is_missing : '%s:%s:%s Missing',
is_invalid : '%s:%s:%s Value Incorrect'
};
}) ()