Source: plugins/wtapi.roster.js

import WTAPI from '../wtapi'
import {JSJaCIQ} from '../jsjac';

/**
 * A plugin that provides Roster functionality
 *
 * @version 1.0.0
 */

var NS_ROSTER = "jabber:iq:roster";

/**
 * Constructor for Roster plugin.
 * Instance will be created each time when new WTAPI instance is created. <br />
 * Plugin could be accessible thought WTAPI with <b>roster</b> property.
 *
 * @tutorial roster-plugin
 * @memberof WTAPI
 * @alias WTAPI.RosterPlugin
 * @augments WTAPI.Observer
 * @public
 * @constructor
 */
function RosterPlugin(wtapi) {
    this._users = {};
    this._wtapi = wtapi;
    this._wtapi.addListener("connected", this._onConnected, this);
    this._wtapi.addListener("disconnected", this._onDisconnected, this);
    this.roster = [];

    // Initialize supper
    WTAPI.Observable.call(this);
}

RosterPlugin.prototype = Object.create(WTAPI.Observable.prototype);

// ============================================================
// Public events
// ============================================================

// ...

// ============================================================
// Public functions
// ============================================================

/**
 * Returns a User for specified jid, or null if user was not created previously.
 *
 * @param {String} jid
 * @returns {WTAPI.User|null}
 */
RosterPlugin.prototype.getUser = function (jid) {
    return jid in this._users ? this._users[jid] : null;
};

/**
 * Returns a User for specified extension, or null if user was not created previously.
 *
 * @param {String} extension
 * @returns {WTAPI.User|null}
 */
RosterPlugin.prototype.getUserByExtension = function (extension) {
    if (this._users) {
        for (var key in this._users) {
            if (this._users[key].getExtension() == extension) {
                return this._users[key];
            }
        }
    }
    return null;
};


/**
 * Retrieves a list of user roster (a list of subscribed colleagues).
 *
 * @param {function} callback
 */
RosterPlugin.prototype.getRoster = function (callback) {
    var scope = arguments[1] || this;
    var packet = this._createGetRosterPacket();
    var handler = this._createGetRosterHandler(callback, scope);
    this._wtapi.getConnection().sendIQ(packet, handler);
};

/**
 * @param {String} jid
 * @param {String} name
 * @returns {WTAPI.User}
 */
RosterPlugin.prototype.createUser = function (jid, name) {
    return this._addUser(new WTAPI.User(jid, name));
};

/**
 *
 * @param {String} extension
 * @returns {WTAPI.User}
 */
RosterPlugin.prototype.createUserByExtension = function (extension) {
    var jid = extension + "@wildix";
    if (this._wtapi.isNewServer()) {
        jid = extension + "@" + this._wtapi.server;
    }
    return this._addUser(new WTAPI.User(jid, null));
};

/**
 *
 * @param {WTAPI.User} user
 * @returns {WTAPI.User}
 * @private
 */
RosterPlugin.prototype._addUser = function (user) {
    if (user.getJid() in this._users) {
        throw new Error("User " + user.getJid() + " already exist");
    }

    this._users[user.getJid()] = user;
    return user;
};

// ============================================================
// RosterPlugin callbacks
// ============================================================

/**
 * @private
 */
RosterPlugin.prototype._onConnected = function () {
};

/**
 * @private
 */
RosterPlugin.prototype._onDisconnected = function () {
};

// ============================================================
// Private functions
// ============================================================

/**
 *
 * @returns {*}
 * @private
 */
RosterPlugin.prototype._createGetRosterPacket = function () {
    var packet = new JSJaCIQ().setType('get');
    packet.setQuery(NS_ROSTER);
    return packet;
};


/**
 *
 * @param callback
 * @param scope
 * @returns {{error_handler: Function, result_handler: Function}}
 * @private
 */
RosterPlugin.prototype._createGetRosterHandler = function (callback, scope) {
    var self = this;
    return {
        result_handler: function (iq) {
            if (typeof callback == 'function') {
                callback.call(scope, self._parseGetRosterResponse(iq));
            }
        },
        error_handler: function () {
            if (typeof callback == 'function') {
                callback.call(scope, []);
            }
        }
    }
};


/**
 *
 * @param packet
 * @returns {WTAPI.User[]}
 * @private
 */
RosterPlugin.prototype._parseGetRosterResponse = function (packet) {
    var node = packet.getNode();
    var items = node.getElementsByTagName('item');
    var result = [];

    for (var i = 0; i < items.length; i++) {
        var item = items.item(i);
        var jid = item.getAttribute("jid");
        var name = item.getAttribute("name");
        var group;
        var groups = item.getElementsByTagName('group');
        if (groups.length > 0 && groups.item(0).firstChild) {
            group = groups.item(0).firstChild.nodeValue;
        }

        // Create new user
        var user = this.getUser(jid);
        if (user === null) {
            user = this.createUser(jid, name);
        }
        user.setGroup(group);
        user.setName(name);

        result.push(user);
    }

    return result;
};

export default RosterPlugin;