UNPKG

allex_libcloudexposurelib

Version:

AllexJS lib that generates the necessary glue code for exposing a lib via the Apartment/Hotel/Service chain

145 lines (136 loc) 5.06 kB
function createServiceMixin (execlib, templateslib, mylib) { 'use strict'; var lib = execlib.lib; var q = lib.q; var qlib = lib.qlib; var execSuite = execlib.execSuite; var taskRegistry = execlib.execSuite.taskRegistry; function serviceMixinCtorListener (mixinname, srvdesc) { var servicename = srvdesc.service; var funcname = servicename.toUpperCase(); var funcpath = servicename.toLowerCase()+'path'; var nofuncpathcode = 'NO_'+funcname+'_PATH_IN_PROPHASH'; return templateslib.process({ template: [ "\tif (!prophash.FUNCTIONALITYPATH) {", "\t\tthrow new lib.Error('NOFUNCPATHCODE', 'Property hash has to have a \"FUNCTIONALITYPATH\" property');", "\t}", "\tthis.findRemote(prophash.FUNCTIONALITYPATH, null, 'FUNCTIONALITYNAME');", "\tthis.state.data.listenFor('FUNCTIONALITYNAME', this.ONNAME.bind(this), true);" ].join('\n'), replacements: { FUNCTIONALITYNAME: funcname, FUNCTIONALITYPATH: funcpath, NOFUNCPATHCODE: nofuncpathcode, ONNAME: 'on'+servicename+'for'+mixinname } }); } //static on hotel service function stateSetter(statename) { console.log('hotel setting', statename, 'to', require('util').inspect(arguments[1], {depth:11})); this.set.apply(this, arguments); } //endof static on hotel service function serviceMixinServiceStateMaterializer (listener) { var template = [ ]; template.push( "\ttaskRegistry.run('readState', {", '\t\tstate: state,', "\t\tname: 'STATEPROP',", listener.debughotel? "\t\tcb: stateSetter.bind(this, 'MYSTATENAME')" : "\t\tcb: this.set.bind(this, 'MYSTATENAME')", '\t});' ); return templateslib.process({ template: template.join('\n'), replacements: { STATEPROP: listener.state, MYSTATENAME: listener.name } }); } function serviceMixinOnServiceCreator (mixinname, srvdesc) { var servicename; if (!lib.isArray(srvdesc.listeners)) { return ''; } servicename = srvdesc.service; return templateslib.process({ template: [ 'ret.prototype.METHODNAME = function (sink) {', '\tvar state;', '\tif (!sink) {', '\t\treturn;', '\t}', "\tstate = taskRegistry.run('materializeState', {sink: sink});", 'READERS', '};' ].join('\n'), replacements: { METHODNAME: 'on'+servicename+'for'+mixinname, READERS: srvdesc.listeners.map(serviceMixinServiceStateMaterializer) } }); } function produceServerMixinCtor (desc) { var ret; var name = desc.name; eval('ret = '+templateslib.process({ template: [ 'function FUNCTIONNAME (prophash) {', 'LISTENERS', '}' ].join('\n'), replacements: { FUNCTIONNAME: desc.name+'ServiceMixin', LISTENERS: (desc.services||[]).map(serviceMixinCtorListener.bind(null, name)).join('\n') } })); eval((desc.services||[]).map(serviceMixinOnServiceCreator.bind(null, name)).join('\n')); name = null; return ret; } function produceServerMixinDtor (ctor, desc) { ctor.prototype.destroy = Function (); } function produceServerMixinMethod (mixin, servicename, methoddescs, methodname) { var methoddescarry = mylib.utils.makeUpDescriptors(methoddescs); var funcparams = methoddescarry.map(mylib.utils.parameterProducer); var methodparams = ['sink'].concat(funcparams).concat(['defer']); var sinkcallparams = ["'"+methodname+"'"].concat(funcparams); var params = methoddescarry.join(', '); eval('mixin.prototype[methodname] = '+templateslib.process({ template: [ "execSuite.dependentServiceMethod([], ['FUNCTIONALITYNAME'], function (METHODPARAMS) {", "\tqlib.promise2defer(sink.call(SINKCALLPARAMS), defer);", "});" ].join('\n'), replacements: { FUNCTIONALITYNAME: servicename.toUpperCase(), METHODNAME: methodname, METHODPARAMS: methodparams.join(', '), SINKCALLPARAMS: sinkcallparams.join(', '), PARAMS: params } })); //mixin.prototype[methodname] = Function.apply (null, funcparams); } function produceServerMixinMethodForService (mixin, servicedesc) { var servicename = servicedesc.service; var _mixin = mixin; lib.traverseShallow(servicedesc.desc, produceServerMixinMethod.bind(null, _mixin, servicename)); _mixin = null; servicename = null; } function produceServiceMixin (desc) { var mixin = produceServerMixinCtor(desc), _mixin = mixin; produceServerMixinDtor(mixin, desc); (desc.services||[]).forEach(produceServerMixinMethodForService.bind(null, _mixin)); mylib.utils.produceAddMethods(mixin, desc); _mixin = null; return mixin; } return produceServiceMixin; } module.exports = createServiceMixin;