/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Gareth Johnson
*/
/**
* Defines {@link baja.NameList}.
* @module baja/obj/NameList
*/
define([ 'bajaScript/sys',
'bajaScript/baja/obj/Simple',
'bajaScript/baja/obj/objUtil',
'bajaScript/baja/ord/SlotPath',
'bajaScript/baja/sys/bajaUtils' ], function (
baja,
Simple,
objUtil,
SlotPath,
bajaUtils) {
'use strict';
var subclass = baja.subclass,
cacheDecode = objUtil.cacheDecode,
cacheEncode = objUtil.cacheEncode,
iterate = bajaUtils.iterate;
/**
* A `NameList` simply contains a set of name strings. Names must be valid
* `SlotPath` names.
*
* Note that the actual behavior of this class is more of a set than a list,
* but we conform with the class name in `javax.baja.util`. Heigh ho.
*
* @class
* @alias baja.NameList
* @extends baja.Simple
*/
var NameList = function NameList() {
Simple.apply(this, arguments);
};
subclass(NameList, Simple);
/**
* Create a new `baja:NameList` instance from a name or set of names.
*
* @param {String|Array.<String>} names a name, or array of names. These must
* all be valid SlotPath names.
* @returns {baja.NameList}
* @throws {Error} if names that are valid SlotPaths are not given
*/
NameList.make = function (names) {
if (typeof names === 'string') { names = [ names ]; }
if (!Array.isArray(names)) { throw new Error('names required'); }
if (!names.length) { return NameList.DEFAULT; }
names.forEach(function (str, i) {
names[i] = names[i].trim();
});
var list = new NameList();
baja.iterate(names, SlotPath.verifyValidName);
list.$names = names;
return list;
};
/**
* Create a new `NameList` which is the union of the two name lists with no
* duplicates.
*
* @param {baja.NameList} a
* @param {baja.NameList} b
* @returns {baja.NameList}
*/
NameList.union = function (a, b) {
var map = {}, result = [];
iterate(a.getNames().concat(b.getNames()), function (n) { map[n] = n; });
iterate(map, function (name) { result.push(name); });
return NameList.make(result);
};
/**
* Create a new `NameList` which is the intersection of the two name lists.
*
* @param {baja.NameList} a
* @param {baja.NameList} b
* @returns {baja.NameList}
*/
NameList.intersection = function (a, b) {
var map = {}, result = [];
iterate(a.getNames(), function (n) { map[n] = true; });
iterate(b.getNames(), function (n) { if (map[n]) { result.push(n); } });
return NameList.make(result);
};
/**
* Create a new `NameList` which is the difference of the two name lists.
*
* @param {baja.NameList} a
* @param {baja.NameList} b
* @returns {baja.NameList}
*/
NameList.difference = function (a, b) {
var map = {}, result = [];
iterate(b.getNames(), function (n) { map[n] = true; });
iterate(a.getNames(), function (n) { if (!map[n]) { result.push(n); } });
return NameList.make(result);
};
/**
* Get the names contained by this `NameList`.
*
* @returns {Array.<String>}
*/
NameList.prototype.getNames = function () {
return this.$names.slice();
};
/**
* Return the difference which is this `NameList` minus the names in the other
* `NameList`.
* @param {baja.NameList} o
* @returns {baja.NameList}
*/
NameList.prototype.difference = function (o) {
return NameList.difference(this, o);
};
/**
* Return the intersection of the names in this `NameList` and the other
* `NameList`.
* @param {baja.NameList} o
* @returns {baja.NameList}
*/
NameList.prototype.intersection = function (o) {
return NameList.intersection(this, o);
};
/**
* Return the union of the names in this `NameList` plus the names in the
* other `NameList`, with no duplicates.
* @param {baja.NameList} o
* @returns {baja.NameList}
*/
NameList.prototype.union = function (o) {
return NameList.union(this, o);
};
/**
* @see .make
* @returns {baja.NameList}
*/
NameList.prototype.make = function () {
return NameList.make.apply(NameList, arguments);
};
/**
* Decode a `NameList` from a string.
*
* @function
* @param {String} str
* @returns {baja.NameList}
*/
NameList.prototype.decodeFromString = cacheDecode(function (str) {
if (!str) {
return NameList.DEFAULT;
}
return NameList.make(str.replace(/;$/, '').split(';'));
});
/**
* Encode this `NameList` to a string.
*
* @function
* @returns {String}
*/
NameList.prototype.encodeToString = cacheEncode(function () {
return this.getNames().join(';');
});
/**
* Two `NameList`s are considered equal if they contain all the same strings,
* not necessarily in the same order.
*
* @param {baja.NameList} o
* @returns {boolean}
*/
NameList.prototype.equals = function (o) {
if (!baja.hasType(o, 'baja:NameList')) { return false; }
return this.getNames().sort().join(';') === o.getNames().sort().join(';');
};
NameList.DEFAULT = NameList.NULL = new NameList();
NameList.DEFAULT.$names = [];
return NameList;
});