UNPKG

base-domain

Version:

simple module to help build Domain-Driven Design

383 lines (292 loc) 9.05 kB
var Base, BaseFactory, extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty; Base = require('./base'); /** Base factory class of DDD pattern. create instance of model the parent "Base" class just simply gives a @getFacade() method. @class BaseFactory @extends Base @module base-domain */ BaseFactory = (function(superClass) { extend(BaseFactory, superClass); /** model name to handle @property modelName @static @protected @type String */ BaseFactory.modelName = null; /** name of dict model to create dict of @modelName @property dictModelName @static @protected @type String */ BaseFactory.dictModelName = null; /** get anonymous factory class @method getAnonymousClass @param {String} modelName @return {Function} */ BaseFactory.getAnonymousClass = function(modelName) { var AnonymousFactory; AnonymousFactory = (function(superClass1) { extend(AnonymousFactory, superClass1); function AnonymousFactory() { return AnonymousFactory.__super__.constructor.apply(this, arguments); } AnonymousFactory.modelName = modelName; AnonymousFactory.isAnonymous = true; return AnonymousFactory; })(BaseFactory); return AnonymousFactory; }; /** constructor @constructor */ function BaseFactory() {} /** get model class this factory handles @method getModelClass @return {Function} */ BaseFactory._ModelClass = void 0; BaseFactory.prototype.getModelClass = function() { return this._ModelClass != null ? this._ModelClass : this._ModelClass = this.getFacade().getModel(this.constructor.modelName); }; /** create empty model instance @method createEmptyModel @return {BaseModel} */ BaseFactory.prototype.createEmptyModel = function() { return this.createFromObject({}); }; BaseFactory.prototype.createEmpty = function() { return this.createFromObject({}); }; /** create instance of model class by plain object for each prop, values are set by Model#set(prop, value) @method createFromObject @public @param {Object} obj @param {BaseModel} baseModel fallback properties @return {BaseModel} model */ BaseFactory.prototype.createFromObject = function(obj) { var ModelClass, model, prop, propInfo, value; ModelClass = this.getModelClass(); if (obj instanceof ModelClass) { return obj; } obj = this.beforeCreateFromObject(obj); if ((obj == null) || typeof obj !== 'object') { return null; } model = new ModelClass(); for (prop in obj) { if (!hasProp.call(obj, prop)) continue; value = obj[prop]; this.setValueToModel(model, prop, value); } propInfo = ModelClass.getPropInfo(); for (prop in propInfo.dic) { if (model[prop] != null) { continue; } this.setEmptyValueToModel(model, prop, propInfo); } return this.afterCreateModel(model); }; /** set value to model in creation @method setValueToModel @private */ BaseFactory.prototype.setValueToModel = function(model, prop, value) { var typeInfo; typeInfo = model.getTypeInfo(prop); switch (typeInfo != null ? typeInfo.name : void 0) { case 'MODEL_LIST': return this.setSubModelListToModel(model, prop, value); case 'MODEL': return this.setSubModelToModel(model, prop, value); case 'MODEL_DICT': return this.setSubModelDictToModel(model, prop, value); default: return model.setNonEntityProp(prop, value); } }; /** set empty values to model in creation @method setEmptyValueToModel @private */ BaseFactory.prototype.setEmptyValueToModel = function(model, prop, propInfo) { var typeInfo; typeInfo = propInfo.getTypeInfo(prop); switch (typeInfo.name) { case 'MODEL': if (propInfo.isEntityProp(prop)) { return this.fetchEntityProp(model, prop, typeInfo); } else { return this.createEmptyNonEntityProp(model, prop, typeInfo); } break; case 'MODEL_LIST': return this.setSubModelListToModel(model, prop, null); case 'MODEL_DICT': return this.setSubModelDictToModel(model, prop, null); default: return model[prop] = void 0; } }; /** creates list and set it to the model @method setSubModelListToModel @private */ BaseFactory.prototype.setSubModelListToModel = function(model, prop, value) { var list, listModelName, subModelFactory, subModelName, typeInfo; typeInfo = model.getTypeInfo(prop); subModelName = typeInfo.model; subModelFactory = this.getFacade().createFactory(subModelName, true); listModelName = typeInfo.listName; list = subModelFactory.createList(listModelName, value); model.setNonEntityProp(prop, list); }; /** set submodel to the prop @method setSubModelToModel @private */ BaseFactory.prototype.setSubModelToModel = function(model, prop, value) { var SubModel, subModelFactory, subModelName, useAnonymousFactory; subModelName = model.getTypeInfo(prop).model; useAnonymousFactory = true; subModelFactory = this.getFacade().createFactory(subModelName, useAnonymousFactory); SubModel = subModelFactory.getModelClass(); if (!(value instanceof SubModel)) { value = subModelFactory.createFromObject(value); } if (SubModel.isEntity) { model.setEntityProp(prop, value); } else { model.setNonEntityProp(prop, value); } }; /** set submodel dict to the prop @method setSubModelToModel @private */ BaseFactory.prototype.setSubModelDictToModel = function(model, prop, value) { var dict, dictModelName, subModelFactory, subModelName, typeInfo; typeInfo = model.getTypeInfo(prop); subModelName = typeInfo.model; subModelFactory = this.getFacade().createFactory(subModelName, true); dictModelName = typeInfo.dictName; dict = subModelFactory.createDict(dictModelName, value); model.setNonEntityProp(prop, dict); }; /** fetch submodel(s) by id available only when repository of submodel implements 'getByIdSync' (MasterRepository implements one) @method fetchEntityProp @private */ BaseFactory.prototype.fetchEntityProp = function(model, prop, typeInfo) { var Repository, e, id, idPropName, repository, subModel; idPropName = typeInfo.idPropName; try { Repository = this.getFacade().getRepository(typeInfo.model); if (!Repository.storeMasterTable) { return; } repository = new Repository(); if (!repository.getByIdSync) { return; } } catch (_error) { e = _error; return; } id = model[idPropName]; subModel = repository.getByIdSync(id); if (subModel) { return model.setEntityProp(prop, subModel); } }; /** create empty non-entity model and set to the prop @method createEmptyNonEntityProp @private */ BaseFactory.prototype.createEmptyNonEntityProp = function(model, prop, typeInfo) { var factory, submodel; factory = this.getFacade().createFactory(typeInfo.model, true); submodel = factory.createEmpty(); return model.setNonEntityProp(prop, submodel); }; /** modify plain object before @createFromObject(obj) @method beforeCreateFromObject @protected @abstract @param {Object} obj @return {Object} obj */ BaseFactory.prototype.beforeCreateFromObject = function(obj) { return obj; }; /** modify model after createFromObject(obj), createEmptyModel() @method afterCreateModel @protected @abstract @param {BaseModel} model @return {BaseModel} model */ BaseFactory.prototype.afterCreateModel = function(model) { return model; }; /** create model list @method createList @public @param {String} listModelName model name of list @param {any} obj @return {BaseList} list */ BaseFactory.prototype.createList = function(listModelName, obj) { var ListFactory, listFactory; ListFactory = this.getFacade().constructor.ListFactory; listFactory = ListFactory.create(listModelName, this); return listFactory.createFromObject(obj); }; /** create model dict @method createDict @public @param {String} dictModelName model name of dict @param {any} obj @return {BaseDict} dict */ BaseFactory.prototype.createDict = function(dictModelName, obj) { var DictFactory, dictFactory; DictFactory = this.getFacade().constructor.DictFactory; dictFactory = DictFactory.create(dictModelName, this); return dictFactory.createFromObject(obj); }; return BaseFactory; })(Base); module.exports = BaseFactory;