var Montage = require("../core").Montage,
ModelModule = require("./model"),
ObjectProperty = require("./object-property").ObjectProperty,
deprecate = require("../deprecate");
/**
* @class ModelGroup
* @classdesc A model group is a singleton that is responsible for
* loading and dispatching object models and descriptors.
*
* @extends Montage
*/
exports.ModelGroup = Montage.specialize( /** @lends ModelGroup.prototype # */ {
/**
* @constructs ModelGroup
*/
constructor: {
value: function ModelGroup() {
this._models = [];
this._modelTable = {};
}
},
_name: {
value: null
},
/**
* Name of the ModelGroup.
* The name is used to define the property on the object.
* @function
* @type {string}
*/
name: {
get: function () {
return this._name;
},
set: function (value) {
if(value !== this._name) {
this._name = value;
}
}
},
/**
* @private
* @property {Array} value
*/
_models: {
value: null
},
/**
* @private
*/
_modelTable: {
value: null
},
/**
* Return the list of binder registered on the manager.
*
* @readonly
* @returns {Array.<Binder>}
*/
models: {
get: function () {
return this._models;
}
},
/**
* Adds an object model to the model group.
*
* @function
* @param {Model} model
*/
addModel: {
value: function (model) {
var index;
if (model !== null) {
if (this._modelTable[model.name]) {
this.removeModel(this._modelTable[model.name]);
}
index = this._models.indexOf(model);
if (index >= 0) {
this._models.splice(index, 1);
}
this._models.push(model);
this._modelTable[model.name] = model;
}
}
},
/**
* @function
* @param {Model} model
*/
removeModel: {
value: function (model) {
var index;
if (model !== null) {
index = this._models.indexOf(model);
if (index >= 0) {
this._models.splice(index, 1);
}
if (this._modelTable[model.name]) {
delete this._modelTable[model.name];
}
}
}
},
/**
* Gets the object model associated with the name.
* @param {string} name
*/
modelForName: {
value: function (name) {
return this._modelTable[name];
}
},
/**
* Search through the models for an object descriptor that extends
* the provided prototype.
* @function
* @param {string} prototypeName
* @param {string} moduleId
* @returns The requested object descriptor or null if this prototype is not
* found.
*/
objectDescriptorForPrototype: {
value: function (prototypeName, moduleId /* unused */) {
var objectDescriptor = null, model, index;
for (index = 0; typeof (model = this.models[index]) !== "undefined" && !objectDescriptor; index++) {
objectDescriptor = model.objectDescriptorForName(prototypeName);
}
return objectDescriptor;
}
},
/**
* @private
*/
_defaultObjectDescriptorObjectProperty: {
serializable: true,
value: null
},
/**
* Return the default object descriptor's object property.
* This is the last resort property declaration object.
*
* @readonly
* @returns {ObjectProperty} default object descriptor object property
*/
defaultObjectDescriptorObjectProperty: {
get: function () {
if (!this._defaultObjectDescriptorObjectProperty) {
this._defaultObjectDescriptorObjectProperty = new ObjectProperty().init();
}
return this._defaultObjectDescriptorObjectProperty;
}
},
_defaultModel: {
serializable: true,
value: null
},
/**
* Return the default model.
* This is the last resort property declaration object.
*
* @readonly
* @returns {Model} default object descriptor model
*/
defaultModel: {
get: function () {
if (!this._defaultModel) {
var _require = global.mr || require; // Handle legacy
this._defaultModel = new ModelModule.Model().initWithNameAndRequire("default", _require);
this._defaultModel.isDefault = true;
this.addModel(this._defaultModel);
}
return this._defaultModel;
}
},
/******************************************************************************
* Deprecated Methods
*/
/**
* Return the list of models registered on the group.
* @deprecated
* @readonly
* @returns {Array.<Binder>}
*/
binders: {
get: deprecate.deprecateMethod(void 0, function () {
return this.models;
}, "binders", "models")
},
/**
* Add a new model
* @deprecated
* @function
* @param {Model} model
*/
addBinder: {
value: deprecate.deprecateMethod(void 0, function (binder) {
this.addModel(binder);
}, "addBinder", "addModel")
},
/**
* @deprecated
* @function
* @param {Binder} binder
*/
removeBinder: {
value: deprecate.deprecateMethod(void 0, function (binder) {
return this.removeModel(binder);
}, "removeBinder", "removeModel")
},
/**
* @deprecated
* Gets the model associated with the name.
* @param {string} name
*/
binderForName: {
value: deprecate.deprecateMethod(void 0, function (name) {
// return this._binderTable[name];
return this.modelForName(name);
}, "binderForName", "modelForName")
},
/**
* Search through the binders for an object descriptor that extends that prototype.
* @deprecated
* @function
* @param {string} prototypeName
* @param {string} moduleId
* @returns The requested object descriptor or null if this prototype is not
* managed.
*/
blueprintForPrototype: {
value: deprecate.deprecateMethod(void 0, function (prototypeName, moduleId) {
return this.objectDescriptorForPrototype(prototypeName);
}, "blueprintForPrototype", "objectDescriptorForPrototype")
},
/**
* Return the default object property.
* This is the last resort property declaration object.
* @deprecated
* @readonly
* @returns {ObjectProperty} default object property
*/
defaultBlueprintObjectProperty: {
get: deprecate.deprecateMethod(void 0, function () {
return this.defaultObjectDescriptorObjectProperty;
}, "defaultBlueprintObjectProperty", "defaultObjectDescriptorObjectProperty")
},
/**
* Return the default model.
*
* @readonly
* @returns {Model} default model
*/
defaultBinder: {
get: deprecate.deprecateMethod(void 0, function () {
return this.defaultModel;
}, "defaultBinder", "defaultModel")
}
});